dscf-credit 0.1.5 → 0.1.6
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/app/controllers/dscf/credit/disbursements_controller.rb +15 -16
- data/app/controllers/dscf/credit/loans_controller.rb +7 -7
- data/app/models/dscf/credit/loan.rb +4 -4
- data/app/serializers/dscf/credit/loan_serializer.rb +1 -2
- data/app/services/dscf/credit/disbursement_service.rb +39 -84
- data/config/locales/en.yml +2 -2
- data/config/routes.rb +0 -2
- data/db/migrate/20250822092654_create_dscf_credit_loans.rb +3 -1
- data/db/seeds.rb +5 -87
- data/lib/dscf/credit/version.rb +1 -1
- data/spec/factories/dscf/credit/loans.rb +5 -1
- metadata +2 -12
- data/app/controllers/dscf/credit/payment_requests_controller.rb +0 -85
- data/app/controllers/dscf/credit/payments_controller.rb +0 -36
- data/app/models/dscf/credit/payment.rb +0 -22
- data/app/models/dscf/credit/payment_request.rb +0 -29
- data/app/serializers/dscf/credit/payment_request_serializer.rb +0 -10
- data/app/serializers/dscf/credit/payment_serializer.rb +0 -8
- data/db/migrate/20250822092608_create_dscf_credit_payment_requests.rb +0 -26
- data/db/migrate/20250822092843_create_dscf_credit_payments.rb +0 -23
- data/spec/factories/dscf/credit/payment_requests.rb +0 -40
- data/spec/factories/dscf/credit/payments.rb +0 -39
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 447633e68d0087ea77917d1630137c52d138096a52039af3c67c577ce3c5edd9
|
4
|
+
data.tar.gz: 5f4b38640b2adf043787cca20d5138b3e40185333f04bb9d747203bd14abf575
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 02ad7c0149c073efb33bbc55e318d6cee9f6096aa29af50ef7316f3caf80ee7396c5cd3fdc7387287e88152e5af9b5854b90620b436fc6487c8c241ec8c1a98a
|
7
|
+
data.tar.gz: '099dd81a6c2f8f788fb38fb6c4f2d8b7f636a0853fbbed972b1078e0da5ef8e6cfe4c7b7fdec5d4bd1d5965e68f93cc8861a3122b20c1f670ebea186dba7c67b'
|
@@ -1,10 +1,15 @@
|
|
1
1
|
module Dscf::Credit
|
2
2
|
class DisbursementsController < ApplicationController
|
3
3
|
def create
|
4
|
-
|
5
|
-
|
4
|
+
amount = disbursement_params[:amount]
|
5
|
+
loan_profile = Dscf::Credit::LoanProfile.find(disbursement_params[:loan_profile_id])
|
6
|
+
eligible_credit_line = Dscf::Credit::EligibleCreditLine.find(disbursement_params[:eligible_credit_line_id])
|
6
7
|
|
7
|
-
service = Dscf::Credit::DisbursementService.new(
|
8
|
+
service = Dscf::Credit::DisbursementService.new(
|
9
|
+
amount: amount,
|
10
|
+
loan_profile: loan_profile,
|
11
|
+
eligible_credit_line: eligible_credit_line
|
12
|
+
)
|
8
13
|
result = service.process_disbursement
|
9
14
|
|
10
15
|
if result[:success]
|
@@ -12,17 +17,7 @@ module Dscf::Credit
|
|
12
17
|
"disbursement.success.create",
|
13
18
|
data: {
|
14
19
|
loan: result[:loan],
|
15
|
-
disbursement_details: result[:disbursement_details]
|
16
|
-
credit_line: credit_line,
|
17
|
-
payment_request: payment_request
|
18
|
-
},
|
19
|
-
serializer_options: {
|
20
|
-
include: [
|
21
|
-
:loan_profile,
|
22
|
-
:credit_line,
|
23
|
-
:payment_request,
|
24
|
-
:loan_transactions
|
25
|
-
]
|
20
|
+
disbursement_details: result[:disbursement_details]
|
26
21
|
}
|
27
22
|
)
|
28
23
|
else
|
@@ -48,8 +43,12 @@ module Dscf::Credit
|
|
48
43
|
|
49
44
|
private
|
50
45
|
|
51
|
-
def
|
52
|
-
params.
|
46
|
+
def disbursement_params
|
47
|
+
params.require(:disbursement).permit(
|
48
|
+
:amount,
|
49
|
+
:loan_profile_id,
|
50
|
+
:eligible_credit_line_id
|
51
|
+
)
|
53
52
|
end
|
54
53
|
end
|
55
54
|
end
|
@@ -8,7 +8,6 @@ module Dscf::Credit
|
|
8
8
|
params.require(:loan).permit(
|
9
9
|
:loan_profile_id,
|
10
10
|
:credit_line_id,
|
11
|
-
:payment_request_id,
|
12
11
|
:status,
|
13
12
|
:principal_amount,
|
14
13
|
:accrued_interest,
|
@@ -17,12 +16,13 @@ module Dscf::Credit
|
|
17
16
|
:total_loan_amount,
|
18
17
|
:remaining_amount,
|
19
18
|
:due_date,
|
20
|
-
:disbursed_at
|
19
|
+
:disbursed_at,
|
20
|
+
:active
|
21
21
|
)
|
22
22
|
end
|
23
23
|
|
24
24
|
def eager_loaded_associations
|
25
|
-
[ :loan_profile, :credit_line, :
|
25
|
+
[ :loan_profile, :credit_line, :loan_transactions ]
|
26
26
|
end
|
27
27
|
|
28
28
|
def allowed_order_columns
|
@@ -31,10 +31,10 @@ module Dscf::Credit
|
|
31
31
|
|
32
32
|
def default_serializer_includes
|
33
33
|
{
|
34
|
-
index: [ :loan_profile, :credit_line
|
35
|
-
show: [ :loan_profile, :credit_line, :
|
36
|
-
create: [ :loan_profile, :credit_line
|
37
|
-
update: [ :loan_profile, :credit_line, :
|
34
|
+
index: [ :loan_profile, :credit_line ],
|
35
|
+
show: [ :loan_profile, :credit_line, :loan_transactions ],
|
36
|
+
create: [ :loan_profile, :credit_line ],
|
37
|
+
update: [ :loan_profile, :credit_line, :loan_transactions ]
|
38
38
|
}
|
39
39
|
end
|
40
40
|
end
|
@@ -4,7 +4,6 @@ module Dscf::Credit
|
|
4
4
|
|
5
5
|
belongs_to :loan_profile, class_name: "Dscf::Credit::LoanProfile", foreign_key: "loan_profile_id"
|
6
6
|
belongs_to :credit_line, class_name: "Dscf::Credit::CreditLine", foreign_key: "credit_line_id"
|
7
|
-
belongs_to :payment_request, class_name: "Dscf::Credit::PaymentRequest", foreign_key: "payment_request_id"
|
8
7
|
has_many :loan_transactions, class_name: "Dscf::Credit::LoanTransaction", foreign_key: "loan_id", dependent: :destroy
|
9
8
|
has_many :daily_routine_transactions, class_name: "Dscf::Credit::DailyRoutineTransaction", foreign_key: "loan_id", dependent: :destroy
|
10
9
|
|
@@ -13,18 +12,19 @@ module Dscf::Credit
|
|
13
12
|
validates :accrued_interest, :accrued_penalty, :facilitation_fee, numericality: { greater_than_or_equal_to: 0 }
|
14
13
|
validates :status, inclusion: { in: %w[pending approved disbursed active overdue paid closed] }
|
15
14
|
|
16
|
-
scope :active, -> { where(
|
15
|
+
scope :active, -> { where(active: true) }
|
16
|
+
scope :inactive, -> { where(active: false) }
|
17
17
|
scope :overdue, -> { where(status: "overdue") }
|
18
18
|
scope :paid, -> { where(status: "paid") }
|
19
19
|
scope :due_today, -> { where(due_date: Date.current) }
|
20
20
|
scope :past_due, -> { where("due_date < ? AND status IN (?)", Date.current, [ "active", "overdue" ]) }
|
21
21
|
|
22
22
|
def self.ransackable_attributes(auth_object = nil)
|
23
|
-
%w[id status principal_amount accrued_interest accrued_penalty facilitation_fee total_loan_amount remaining_amount due_date disbursed_at created_at updated_at]
|
23
|
+
%w[id status principal_amount accrued_interest accrued_penalty facilitation_fee total_loan_amount remaining_amount due_date disbursed_at active created_at updated_at]
|
24
24
|
end
|
25
25
|
|
26
26
|
def self.ransackable_associations(auth_object = nil)
|
27
|
-
%w[loan_profile credit_line
|
27
|
+
%w[loan_profile credit_line loan_transactions daily_routine_transactions]
|
28
28
|
end
|
29
29
|
|
30
30
|
delegate :user, to: :loan_profile, allow_nil: true
|
@@ -1,11 +1,10 @@
|
|
1
1
|
module Dscf::Credit
|
2
2
|
class LoanSerializer < ActiveModel::Serializer
|
3
3
|
attributes :id, :status, :principal_amount, :accrued_interest, :accrued_penalty, :facilitation_fee,
|
4
|
-
:total_loan_amount, :remaining_amount, :due_date, :disbursed_at, :created_at, :updated_at
|
4
|
+
:total_loan_amount, :remaining_amount, :due_date, :disbursed_at, :active, :created_at, :updated_at
|
5
5
|
|
6
6
|
belongs_to :loan_profile, serializer: LoanProfileSerializer
|
7
7
|
belongs_to :credit_line, serializer: CreditLineSerializer
|
8
|
-
belongs_to :payment_request, serializer: PaymentRequestSerializer
|
9
8
|
has_many :loan_transactions, serializer: LoanTransactionSerializer
|
10
9
|
has_many :daily_routine_transactions, serializer: DailyRoutineTransactionSerializer
|
11
10
|
end
|
@@ -1,34 +1,35 @@
|
|
1
1
|
module Dscf::Credit
|
2
2
|
class DisbursementService
|
3
|
-
attr_reader :
|
3
|
+
attr_reader :amount, :loan_profile, :eligible_credit_line
|
4
4
|
|
5
|
-
def initialize(
|
6
|
-
@
|
7
|
-
@
|
8
|
-
@
|
5
|
+
def initialize(amount:, loan_profile:, eligible_credit_line:)
|
6
|
+
@amount = amount.to_f
|
7
|
+
@loan_profile = loan_profile
|
8
|
+
@eligible_credit_line = eligible_credit_line
|
9
9
|
end
|
10
10
|
|
11
|
-
# Process disbursement by creating a loan record from
|
11
|
+
# Process disbursement by creating a loan record from eligible credit line
|
12
12
|
# @return [Hash] Result containing created loan and disbursement details
|
13
13
|
def process_disbursement
|
14
|
+
return error_result("Loan profile not found") unless loan_profile
|
15
|
+
return error_result("Eligible credit line not found") unless eligible_credit_line
|
16
|
+
return error_result("Invalid amount") unless amount > 0
|
17
|
+
|
18
|
+
credit_line = eligible_credit_line.credit_line
|
14
19
|
return error_result("Credit line not found") unless credit_line
|
15
|
-
return error_result("Payment request not found") unless payment_request
|
16
|
-
return error_result("Credit line is not approved") unless credit_line.status == "approved"
|
17
20
|
|
18
|
-
|
19
|
-
return error_result("
|
21
|
+
credit_line_status = credit_line.current_status_for(:default)
|
22
|
+
return error_result("Credit line is not approved") unless credit_line_status == "approved"
|
20
23
|
|
21
|
-
|
22
|
-
return error_result("Loan profile not approved") unless
|
24
|
+
loan_profile_status = loan_profile.current_status_for(:default)
|
25
|
+
return error_result("Loan profile not approved") unless loan_profile_status == "approved"
|
23
26
|
|
24
|
-
validation_result = validate_disbursement_amount
|
27
|
+
validation_result = validate_disbursement_amount
|
25
28
|
return validation_result unless validation_result[:success]
|
26
29
|
|
27
30
|
ActiveRecord::Base.transaction do
|
28
|
-
loan = create_loan_record(
|
29
|
-
|
30
|
-
update_credit_line_limits(eligible_credit_line, loan)
|
31
|
-
lock_other_credit_lines(loan_profile, credit_line)
|
31
|
+
loan = create_loan_record(credit_line)
|
32
|
+
update_credit_line_limits(loan)
|
32
33
|
|
33
34
|
success_result(loan)
|
34
35
|
end
|
@@ -38,36 +39,27 @@ module Dscf::Credit
|
|
38
39
|
|
39
40
|
private
|
40
41
|
|
41
|
-
def
|
42
|
-
credit_line.eligible_credit_lines
|
43
|
-
.joins(:loan_profile)
|
44
|
-
.where(dscf_credit_loan_profiles: { status: "approved" })
|
45
|
-
.first
|
46
|
-
end
|
47
|
-
|
48
|
-
def validate_disbursement_amount(eligible_credit_line)
|
49
|
-
requested_amount = payment_request.amount
|
42
|
+
def validate_disbursement_amount
|
50
43
|
available_limit = eligible_credit_line.available_limit
|
51
44
|
|
52
|
-
if
|
45
|
+
if amount <= 0
|
53
46
|
return error_result("Invalid disbursement amount")
|
54
47
|
end
|
55
48
|
|
56
|
-
if
|
49
|
+
if amount > available_limit
|
57
50
|
return error_result("Requested amount exceeds available credit limit")
|
58
51
|
end
|
59
52
|
|
60
53
|
{ success: true }
|
61
54
|
end
|
62
55
|
|
63
|
-
def create_loan_record(
|
64
|
-
loan_terms = calculate_loan_terms(
|
56
|
+
def create_loan_record(credit_line)
|
57
|
+
loan_terms = calculate_loan_terms(credit_line)
|
65
58
|
|
66
59
|
loan = Dscf::Credit::Loan.new(
|
67
60
|
loan_profile: loan_profile,
|
68
61
|
credit_line: credit_line,
|
69
|
-
|
70
|
-
principal_amount: payment_request.amount,
|
62
|
+
principal_amount: amount,
|
71
63
|
facilitation_fee: loan_terms[:facilitation_fee],
|
72
64
|
total_loan_amount: loan_terms[:total_amount],
|
73
65
|
remaining_amount: loan_terms[:total_amount],
|
@@ -75,7 +67,8 @@ module Dscf::Credit
|
|
75
67
|
accrued_penalty: 0,
|
76
68
|
status: "disbursed",
|
77
69
|
due_date: loan_terms[:due_date],
|
78
|
-
disbursed_at: Time.current
|
70
|
+
disbursed_at: Time.current,
|
71
|
+
active: true
|
79
72
|
)
|
80
73
|
|
81
74
|
raise "Failed to create loan: #{loan.errors.full_messages.join(', ')}" unless loan.save
|
@@ -83,21 +76,20 @@ module Dscf::Credit
|
|
83
76
|
loan
|
84
77
|
end
|
85
78
|
|
86
|
-
def calculate_loan_terms(
|
87
|
-
principal =
|
79
|
+
def calculate_loan_terms(credit_line)
|
80
|
+
principal = amount
|
88
81
|
|
89
82
|
credit_line_spec = credit_line.credit_line_specs.active.first
|
90
83
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
loan_duration = credit_line_spec.loan_duration
|
95
|
-
else
|
96
|
-
facilitation_rate = 0.02 # 2%
|
97
|
-
vat_rate = 0.15 # 15%
|
98
|
-
loan_duration = 30 # 30 days
|
84
|
+
unless credit_line_spec
|
85
|
+
raise "No active credit line specification found for credit line #{credit_line.id}. " \
|
86
|
+
"Please configure a CreditLineSpec before processing disbursements."
|
99
87
|
end
|
100
88
|
|
89
|
+
facilitation_rate = credit_line_spec.facilitation_fee_rate
|
90
|
+
vat_rate = credit_line_spec.vat
|
91
|
+
loan_duration = credit_line_spec.loan_duration
|
92
|
+
|
101
93
|
facilitation_fee = principal * facilitation_rate
|
102
94
|
vat_amount = facilitation_fee * vat_rate
|
103
95
|
total_amount = principal + facilitation_fee + vat_amount
|
@@ -112,46 +104,9 @@ module Dscf::Credit
|
|
112
104
|
}
|
113
105
|
end
|
114
106
|
|
115
|
-
def
|
116
|
-
payment_request.update!(
|
117
|
-
status: "processed",
|
118
|
-
approved_at: Time.current
|
119
|
-
)
|
120
|
-
|
121
|
-
Dscf::Credit::LoanTransaction.create!(
|
122
|
-
loan: loan,
|
123
|
-
transaction_type: "disbursement",
|
124
|
-
amount: loan.principal_amount,
|
125
|
-
transaction_reference: "DISB-#{payment_request.order_id}-#{Time.current.to_i}",
|
126
|
-
status: "completed"
|
127
|
-
)
|
128
|
-
|
129
|
-
if loan.facilitation_fee > 0
|
130
|
-
Dscf::Credit::LoanTransaction.create!(
|
131
|
-
loan: loan,
|
132
|
-
transaction_type: "fee_charge",
|
133
|
-
amount: loan.facilitation_fee,
|
134
|
-
transaction_reference: "FEE-#{loan.id}-#{Time.current.to_i}",
|
135
|
-
status: "completed"
|
136
|
-
)
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
def update_credit_line_limits(eligible_credit_line, loan)
|
107
|
+
def update_credit_line_limits(loan)
|
141
108
|
new_available_limit = eligible_credit_line.available_limit - loan.total_loan_amount
|
142
109
|
eligible_credit_line.update!(available_limit: [ new_available_limit, 0 ].max)
|
143
|
-
|
144
|
-
# Update loan profile available amount
|
145
|
-
loan_profile = eligible_credit_line.loan_profile
|
146
|
-
new_profile_available = loan_profile.available_amount - loan.total_loan_amount
|
147
|
-
loan_profile.update!(available_amount: [ new_profile_available, 0 ].max)
|
148
|
-
end
|
149
|
-
|
150
|
-
def lock_other_credit_lines(loan_profile, current_credit_line)
|
151
|
-
other_eligible_lines = loan_profile.eligible_credit_lines
|
152
|
-
.where.not(credit_line: current_credit_line)
|
153
|
-
|
154
|
-
other_eligible_lines.update_all(available_limit: 0)
|
155
110
|
end
|
156
111
|
|
157
112
|
def success_result(loan)
|
@@ -159,9 +114,9 @@ module Dscf::Credit
|
|
159
114
|
success: true,
|
160
115
|
loan: loan,
|
161
116
|
disbursement_details: {
|
162
|
-
principal_amount: loan.principal_amount,
|
163
|
-
facilitation_fee: loan.facilitation_fee,
|
164
|
-
total_loan_amount: loan.total_loan_amount,
|
117
|
+
principal_amount: loan.principal_amount.to_f,
|
118
|
+
facilitation_fee: loan.facilitation_fee.to_f,
|
119
|
+
total_loan_amount: loan.total_loan_amount.to_f,
|
165
120
|
due_date: loan.due_date,
|
166
121
|
disbursed_at: loan.disbursed_at
|
167
122
|
},
|
data/config/locales/en.yml
CHANGED
@@ -328,10 +328,10 @@ en:
|
|
328
328
|
|
329
329
|
disbursement:
|
330
330
|
success:
|
331
|
-
create: "Disbursement processed successfully"
|
331
|
+
create: "Disbursement processed successfully. Loan created and credit limit updated."
|
332
332
|
errors:
|
333
333
|
create: "Failed to process disbursement"
|
334
|
-
not_found: "
|
334
|
+
not_found: "Loan profile or eligible credit line not found"
|
335
335
|
|
336
336
|
repayment:
|
337
337
|
success:
|
data/config/routes.rb
CHANGED
@@ -18,7 +18,6 @@ Dscf::Credit::Engine.routes.draw do
|
|
18
18
|
member do
|
19
19
|
patch "approve"
|
20
20
|
patch "reject"
|
21
|
-
post "calculate_score"
|
22
21
|
post "calculate_facility_limits"
|
23
22
|
end
|
24
23
|
end
|
@@ -78,7 +77,6 @@ Dscf::Credit::Engine.routes.draw do
|
|
78
77
|
patch "update_facilitator_info"
|
79
78
|
patch "update_field_assessment"
|
80
79
|
post "calculate_credit_score"
|
81
|
-
patch "apply_risk_factor"
|
82
80
|
end
|
83
81
|
end
|
84
82
|
|
@@ -3,7 +3,6 @@ class CreateDscfCreditLoans < ActiveRecord::Migration[8.0]
|
|
3
3
|
create_table :dscf_credit_loans do |t|
|
4
4
|
t.references :loan_profile, null: false, foreign_key: { to_table: :dscf_credit_loan_profiles }
|
5
5
|
t.references :credit_line, null: false, foreign_key: { to_table: :dscf_credit_credit_lines }
|
6
|
-
t.references :payment_request, null: false, foreign_key: { to_table: :dscf_credit_payment_requests }
|
7
6
|
t.string :status, default: 'pending'
|
8
7
|
t.decimal :principal_amount, precision: 15, scale: 2, null: false
|
9
8
|
t.decimal :accrued_interest, precision: 15, scale: 2, default: 0
|
@@ -13,6 +12,7 @@ class CreateDscfCreditLoans < ActiveRecord::Migration[8.0]
|
|
13
12
|
t.decimal :remaining_amount, precision: 15, scale: 2, null: false
|
14
13
|
t.date :due_date, null: false
|
15
14
|
t.datetime :disbursed_at
|
15
|
+
t.boolean :active, default: true, null: false
|
16
16
|
|
17
17
|
t.timestamps
|
18
18
|
end
|
@@ -22,8 +22,10 @@ class CreateDscfCreditLoans < ActiveRecord::Migration[8.0]
|
|
22
22
|
add_index :dscf_credit_loans, :disbursed_at
|
23
23
|
add_index :dscf_credit_loans, :principal_amount
|
24
24
|
add_index :dscf_credit_loans, :remaining_amount
|
25
|
+
add_index :dscf_credit_loans, :active
|
25
26
|
add_index :dscf_credit_loans, [ :loan_profile_id, :status ]
|
26
27
|
add_index :dscf_credit_loans, [ :credit_line_id, :status ]
|
27
28
|
add_index :dscf_credit_loans, [ :status, :due_date ]
|
29
|
+
add_index :dscf_credit_loans, [ :active, :status ]
|
28
30
|
end
|
29
31
|
end
|
data/db/seeds.rb
CHANGED
@@ -804,35 +804,11 @@ Dscf::Credit::EligibleCreditLine.create!(
|
|
804
804
|
risk: 0.45
|
805
805
|
)
|
806
806
|
|
807
|
-
# 12.
|
808
|
-
puts "Seeding payment requests..."
|
809
|
-
payment_request1 = Dscf::Credit::PaymentRequest.create!(
|
810
|
-
user: user2,
|
811
|
-
order_id: "ORD-#{Time.current.to_i}-001",
|
812
|
-
request_type: 'loan_disbursement',
|
813
|
-
amount: 50000.00,
|
814
|
-
receiver_account_reference: 'ACC-BORROWER-001',
|
815
|
-
status: 'approved',
|
816
|
-
initiated_at: 2.days.ago,
|
817
|
-
approved_at: 1.day.ago
|
818
|
-
)
|
819
|
-
|
820
|
-
payment_request2 = Dscf::Credit::PaymentRequest.create!(
|
821
|
-
user: user2,
|
822
|
-
order_id: "ORD-#{Time.current.to_i}-002",
|
823
|
-
request_type: 'loan_repayment',
|
824
|
-
amount: 15000.00,
|
825
|
-
receiver_account_reference: 'ACC-BANK-001',
|
826
|
-
status: 'pending',
|
827
|
-
initiated_at: 1.hour.ago
|
828
|
-
)
|
829
|
-
|
830
|
-
# 13. Loans (depends on loan profiles, credit lines, and payment requests)
|
807
|
+
# 12. Loans (depends on loan profiles and credit lines)
|
831
808
|
puts "Seeding loans..."
|
832
809
|
loan1 = Dscf::Credit::Loan.create!(
|
833
810
|
loan_profile: loan_profile1,
|
834
811
|
credit_line: credit_line1,
|
835
|
-
payment_request: payment_request1,
|
836
812
|
status: 'active',
|
837
813
|
principal_amount: 50000.00,
|
838
814
|
accrued_interest: 2500.00,
|
@@ -841,10 +817,11 @@ loan1 = Dscf::Credit::Loan.create!(
|
|
841
817
|
total_loan_amount: 53500.00,
|
842
818
|
remaining_amount: 53500.00,
|
843
819
|
due_date: 3.months.from_now.to_date,
|
844
|
-
disbursed_at: 1.day.ago
|
820
|
+
disbursed_at: 1.day.ago,
|
821
|
+
active: true
|
845
822
|
)
|
846
823
|
|
847
|
-
#
|
824
|
+
# 13. Loan Transactions (depends on loans)
|
848
825
|
puts "Seeding loan transactions..."
|
849
826
|
Dscf::Credit::LoanTransaction.create!(
|
850
827
|
loan: loan1,
|
@@ -862,7 +839,7 @@ Dscf::Credit::LoanTransaction.create!(
|
|
862
839
|
status: 'completed'
|
863
840
|
)
|
864
841
|
|
865
|
-
#
|
842
|
+
# 14. Daily Routine Transactions (depends on loans)
|
866
843
|
puts "Seeding daily routine transactions..."
|
867
844
|
Dscf::Credit::DailyRoutineTransaction.create!(
|
868
845
|
loan: loan1,
|
@@ -873,63 +850,6 @@ Dscf::Credit::DailyRoutineTransaction.create!(
|
|
873
850
|
approved_at: Date.current.beginning_of_day + 1.hour
|
874
851
|
)
|
875
852
|
|
876
|
-
# 16. Payments (depends on payment requests)
|
877
|
-
puts "Seeding payments..."
|
878
|
-
Dscf::Credit::Payment.create!(
|
879
|
-
payment_request: payment_request1,
|
880
|
-
amount: 50000.00,
|
881
|
-
receiver_account_reference: 'ACC-BORROWER-001',
|
882
|
-
transaction_reference: "PAY-#{Time.current.to_i}-001",
|
883
|
-
status: 'completed',
|
884
|
-
processed_at: 1.day.ago
|
885
|
-
)
|
886
|
-
|
887
|
-
# 17. Accounting Audit Requests (depends on various entities)
|
888
|
-
puts "Seeding accounting audit requests..."
|
889
|
-
audit_request1 = Dscf::Credit::AccountingAuditRequest.create!(
|
890
|
-
source_entity: loan1,
|
891
|
-
transaction_type: 'debit',
|
892
|
-
amount: 50000.00,
|
893
|
-
webhook_key: "WEBHOOK-#{SecureRandom.hex(16)}",
|
894
|
-
status: 'completed'
|
895
|
-
)
|
896
|
-
|
897
|
-
Dscf::Credit::AccountingAuditRequest.create!(
|
898
|
-
source_entity: payment_request1,
|
899
|
-
transaction_type: 'transfer',
|
900
|
-
amount: 50000.00,
|
901
|
-
webhook_key: "WEBHOOK-#{SecureRandom.hex(16)}",
|
902
|
-
status: 'pending'
|
903
|
-
)
|
904
|
-
|
905
|
-
# 18. Accounting Entries (depends on audit requests)
|
906
|
-
puts "Seeding accounting entries..."
|
907
|
-
Dscf::Credit::AccountingEntry.create!(
|
908
|
-
audit_request: audit_request1,
|
909
|
-
account_code: 'LOAN_ASSET_001',
|
910
|
-
entry_type: 'debit',
|
911
|
-
amount: 50000.00,
|
912
|
-
status: 'completed'
|
913
|
-
)
|
914
|
-
|
915
|
-
Dscf::Credit::AccountingEntry.create!(
|
916
|
-
audit_request: audit_request1,
|
917
|
-
account_code: 'CASH_001',
|
918
|
-
entry_type: 'credit',
|
919
|
-
amount: 50000.00,
|
920
|
-
status: 'completed'
|
921
|
-
)
|
922
|
-
|
923
|
-
# 19. Failed Operations Logs (depends on various entities)
|
924
|
-
puts "Seeding failed operations logs..."
|
925
|
-
Dscf::Credit::FailedOperationsLog.create!(
|
926
|
-
entity: payment_request2,
|
927
|
-
failure_type: 'payment_processing',
|
928
|
-
reason: 'Payment gateway did not respond within timeout period',
|
929
|
-
retry_count: 2,
|
930
|
-
resolved: false
|
931
|
-
)
|
932
|
-
|
933
853
|
puts "DSCF Credit Engine seed data completed successfully!"
|
934
854
|
puts "Created sample data for all models with proper relationships."
|
935
855
|
puts "Summary:"
|
@@ -943,8 +863,6 @@ puts "- Categories: #{Dscf::Credit::Category.count}"
|
|
943
863
|
puts "- Credit Lines: #{Dscf::Credit::CreditLine.count}"
|
944
864
|
puts "- Loan Profiles: #{Dscf::Credit::LoanProfile.count}"
|
945
865
|
puts "- Loans: #{Dscf::Credit::Loan.count}"
|
946
|
-
puts "- Payment Requests: #{Dscf::Credit::PaymentRequest.count}"
|
947
|
-
puts "- Payments: #{Dscf::Credit::Payment.count}"
|
948
866
|
puts "- Facilitators: #{Dscf::Credit::Facilitator.count} (will be created via API)"
|
949
867
|
puts "- System Configs: #{Dscf::Credit::SystemConfig.count}"
|
950
868
|
puts "- Scoring Parameters: #{Dscf::Credit::ScoringParameter.count}"
|
data/lib/dscf/credit/version.rb
CHANGED
@@ -2,7 +2,6 @@ FactoryBot.define do
|
|
2
2
|
factory :loan, class: "Dscf::Credit::Loan" do
|
3
3
|
association :loan_profile, factory: :loan_profile
|
4
4
|
association :credit_line, factory: :credit_line
|
5
|
-
association :payment_request, factory: :payment_request
|
6
5
|
status { %w[pending approved disbursed active overdue paid closed].sample }
|
7
6
|
principal_amount { Faker::Number.decimal(l_digits: 5, r_digits: 2) }
|
8
7
|
accrued_interest { Faker::Number.decimal(l_digits: 3, r_digits: 2) }
|
@@ -12,6 +11,7 @@ FactoryBot.define do
|
|
12
11
|
remaining_amount { Faker::Number.decimal(l_digits: 5, r_digits: 2) }
|
13
12
|
due_date { Faker::Date.between(from: 1.month.from_now, to: 6.months.from_now) }
|
14
13
|
disbursed_at { Faker::Time.between(from: 2.months.ago, to: Time.current) if status.in?(%w[disbursed active overdue paid closed]) }
|
14
|
+
active { true }
|
15
15
|
|
16
16
|
trait :pending do
|
17
17
|
status { "pending" }
|
@@ -33,5 +33,9 @@ FactoryBot.define do
|
|
33
33
|
status { "paid" }
|
34
34
|
remaining_amount { 0 }
|
35
35
|
end
|
36
|
+
|
37
|
+
trait :inactive do
|
38
|
+
active { false }
|
39
|
+
end
|
36
40
|
end
|
37
41
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dscf-credit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adoniyas
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-
|
10
|
+
date: 2025-10-01 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: dscf-core
|
@@ -337,8 +337,6 @@ files:
|
|
337
337
|
- app/controllers/dscf/credit/loan_profiles_controller.rb
|
338
338
|
- app/controllers/dscf/credit/loans_controller.rb
|
339
339
|
- app/controllers/dscf/credit/parameter_normalizers_controller.rb
|
340
|
-
- app/controllers/dscf/credit/payment_requests_controller.rb
|
341
|
-
- app/controllers/dscf/credit/payments_controller.rb
|
342
340
|
- app/controllers/dscf/credit/repayments_controller.rb
|
343
341
|
- app/controllers/dscf/credit/scoring_param_types_controller.rb
|
344
342
|
- app/controllers/dscf/credit/scoring_parameters_controller.rb
|
@@ -371,8 +369,6 @@ files:
|
|
371
369
|
- app/models/dscf/credit/loan_profile_scoring_spec.rb
|
372
370
|
- app/models/dscf/credit/loan_transaction.rb
|
373
371
|
- app/models/dscf/credit/parameter_normalizer.rb
|
374
|
-
- app/models/dscf/credit/payment.rb
|
375
|
-
- app/models/dscf/credit/payment_request.rb
|
376
372
|
- app/models/dscf/credit/scoring_param_type.rb
|
377
373
|
- app/models/dscf/credit/scoring_parameter.rb
|
378
374
|
- app/models/dscf/credit/system_config.rb
|
@@ -400,8 +396,6 @@ files:
|
|
400
396
|
- app/serializers/dscf/credit/loan_serializer.rb
|
401
397
|
- app/serializers/dscf/credit/loan_transaction_serializer.rb
|
402
398
|
- app/serializers/dscf/credit/parameter_normalizer_serializer.rb
|
403
|
-
- app/serializers/dscf/credit/payment_request_serializer.rb
|
404
|
-
- app/serializers/dscf/credit/payment_serializer.rb
|
405
399
|
- app/serializers/dscf/credit/scoring_param_type_serializer.rb
|
406
400
|
- app/serializers/dscf/credit/scoring_parameter_serializer.rb
|
407
401
|
- app/serializers/dscf/credit/system_config_definition_serializer.rb
|
@@ -448,12 +442,10 @@ files:
|
|
448
442
|
- db/migrate/20250822092426_create_dscf_credit_facilitator_applications.rb
|
449
443
|
- db/migrate/20250822092436_create_dscf_credit_facilitators.rb
|
450
444
|
- db/migrate/20250822092528_create_dscf_credit_facilitator_performances.rb
|
451
|
-
- db/migrate/20250822092608_create_dscf_credit_payment_requests.rb
|
452
445
|
- db/migrate/20250822092654_create_dscf_credit_loans.rb
|
453
446
|
- db/migrate/20250822092717_create_dscf_credit_loan_transactions.rb
|
454
447
|
- db/migrate/20250822092738_create_dscf_credit_daily_routine_transactions.rb
|
455
448
|
- db/migrate/20250822092819_create_dscf_credit_accounting_audit_requests.rb
|
456
|
-
- db/migrate/20250822092843_create_dscf_credit_payments.rb
|
457
449
|
- db/migrate/20250822092908_create_dscf_credit_failed_operations_logs.rb
|
458
450
|
- db/migrate/20250822092936_create_dscf_credit_accounting_entries.rb
|
459
451
|
- db/migrate/20250825231109_create_dscf_credit_bank_staff.rb
|
@@ -483,8 +475,6 @@ files:
|
|
483
475
|
- spec/factories/dscf/credit/loan_transactions.rb
|
484
476
|
- spec/factories/dscf/credit/loans.rb
|
485
477
|
- spec/factories/dscf/credit/parameter_normalizers.rb
|
486
|
-
- spec/factories/dscf/credit/payment_requests.rb
|
487
|
-
- spec/factories/dscf/credit/payments.rb
|
488
478
|
- spec/factories/dscf/credit/scoring_param_types.rb
|
489
479
|
- spec/factories/dscf/credit/scoring_parameters.rb
|
490
480
|
- spec/factories/dscf/credit/system_config_definitions.rb
|
@@ -1,85 +0,0 @@
|
|
1
|
-
module Dscf::Credit
|
2
|
-
class PaymentRequestsController < ApplicationController
|
3
|
-
include Dscf::Core::Common
|
4
|
-
|
5
|
-
def create
|
6
|
-
super do
|
7
|
-
obj = @clazz.new(model_params)
|
8
|
-
obj.request_type = "credit"
|
9
|
-
obj.initiated_at = Time.current
|
10
|
-
obj
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
def approve
|
15
|
-
@obj = @clazz.find(params[:id])
|
16
|
-
|
17
|
-
if @obj.update(status: "approved", approved_at: Time.current)
|
18
|
-
@obj = @clazz.includes(eager_loaded_associations).find(@obj.id) if eager_loaded_associations.present?
|
19
|
-
includes = serializer_includes_for_action(:show)
|
20
|
-
options = includes.present? ? { include: includes } : {}
|
21
|
-
render_success(data: @obj, serializer_options: options)
|
22
|
-
else
|
23
|
-
render_error(errors: @obj.errors.full_messages[0], status: :unprocessable_entity)
|
24
|
-
end
|
25
|
-
rescue StandardError => e
|
26
|
-
render_error(error: e.message)
|
27
|
-
end
|
28
|
-
|
29
|
-
def eligible_credit_lines
|
30
|
-
payment_request = @clazz.find(params[:id])
|
31
|
-
|
32
|
-
if payment_request.user.nil?
|
33
|
-
return render_error(error: "Payment request has no associated user", status: :unprocessable_entity)
|
34
|
-
end
|
35
|
-
|
36
|
-
# Find all eligible credit lines for the user through their approved loan profiles
|
37
|
-
# Only include credit lines with available credit
|
38
|
-
eligible_credit_lines = Dscf::Credit::EligibleCreditLine
|
39
|
-
.joins(loan_profile: [ { loan_application: :user }, :reviews ])
|
40
|
-
.where(dscf_credit_loan_applications: { user_id: payment_request.user_id })
|
41
|
-
.where(dscf_core_reviews: { status: "approved" }) # Only approved loan profiles via reviews
|
42
|
-
.where("dscf_credit_eligible_credit_lines.available_limit > 0") # Only with available credit
|
43
|
-
.includes(:loan_profile, :credit_line)
|
44
|
-
.order("dscf_credit_eligible_credit_lines.available_limit DESC") # Order by available limit
|
45
|
-
|
46
|
-
render_success(
|
47
|
-
data: eligible_credit_lines,
|
48
|
-
)
|
49
|
-
rescue ActiveRecord::RecordNotFound
|
50
|
-
render_error(error: "Payment request not found", status: :not_found)
|
51
|
-
rescue StandardError => e
|
52
|
-
render_error(error: e.message)
|
53
|
-
end
|
54
|
-
|
55
|
-
private
|
56
|
-
|
57
|
-
def model_params
|
58
|
-
params.require(:payment_request).permit(
|
59
|
-
:user_id,
|
60
|
-
:order_id,
|
61
|
-
:amount,
|
62
|
-
:receiver_account_reference,
|
63
|
-
:status,
|
64
|
-
:failure_reason
|
65
|
-
)
|
66
|
-
end
|
67
|
-
|
68
|
-
def eager_loaded_associations
|
69
|
-
[ :user, :loans, :payments ]
|
70
|
-
end
|
71
|
-
|
72
|
-
def allowed_order_columns
|
73
|
-
%w[id order_id request_type amount status initiated_at approved_at created_at updated_at]
|
74
|
-
end
|
75
|
-
|
76
|
-
def default_serializer_includes
|
77
|
-
{
|
78
|
-
index: [ :user ],
|
79
|
-
show: [ :user, :loans, :payments ],
|
80
|
-
create: [ :user ],
|
81
|
-
update: [ :user, :loans, :payments ]
|
82
|
-
}
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
@@ -1,36 +0,0 @@
|
|
1
|
-
module Dscf::Credit
|
2
|
-
class PaymentsController < ApplicationController
|
3
|
-
include Dscf::Core::Common
|
4
|
-
|
5
|
-
private
|
6
|
-
|
7
|
-
def model_params
|
8
|
-
params.require(:payment).permit(
|
9
|
-
:payment_request_id,
|
10
|
-
:amount,
|
11
|
-
:receiver_account_reference,
|
12
|
-
:transaction_reference,
|
13
|
-
:status,
|
14
|
-
:failure_reason,
|
15
|
-
:processed_at
|
16
|
-
)
|
17
|
-
end
|
18
|
-
|
19
|
-
def eager_loaded_associations
|
20
|
-
[ :payment_request ]
|
21
|
-
end
|
22
|
-
|
23
|
-
def allowed_order_columns
|
24
|
-
%w[id amount status processed_at created_at updated_at]
|
25
|
-
end
|
26
|
-
|
27
|
-
def default_serializer_includes
|
28
|
-
{
|
29
|
-
index: [ :payment_request ],
|
30
|
-
show: [ :payment_request ],
|
31
|
-
create: [ :payment_request ],
|
32
|
-
update: [ :payment_request ]
|
33
|
-
}
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
@@ -1,22 +0,0 @@
|
|
1
|
-
module Dscf::Credit
|
2
|
-
class Payment < ApplicationRecord
|
3
|
-
self.table_name = "dscf_credit_payments"
|
4
|
-
|
5
|
-
belongs_to :payment_request, class_name: "Dscf::Credit::PaymentRequest", foreign_key: "payment_request_id"
|
6
|
-
|
7
|
-
validates :amount, :receiver_account_reference, :transaction_reference, :status, presence: true
|
8
|
-
validates :amount, numericality: { greater_than: 0 }
|
9
|
-
validates :status, inclusion: { in: %w[pending processing completed failed cancelled] }
|
10
|
-
validates :transaction_reference, uniqueness: true
|
11
|
-
|
12
|
-
scope :by_status, ->(status) { where(status: status) }
|
13
|
-
|
14
|
-
def self.ransackable_attributes(auth_object = nil)
|
15
|
-
%w[id amount receiver_account_reference transaction_reference status failure_reason processed_at created_at updated_at]
|
16
|
-
end
|
17
|
-
|
18
|
-
def self.ransackable_associations(auth_object = nil)
|
19
|
-
%w[payment_request]
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
module Dscf::Credit
|
2
|
-
class PaymentRequest < ApplicationRecord
|
3
|
-
self.table_name = "dscf_credit_payment_requests"
|
4
|
-
|
5
|
-
if defined?(Dscf::Core::User)
|
6
|
-
belongs_to :user, class_name: "Dscf::Core::User", foreign_key: "user_id"
|
7
|
-
end
|
8
|
-
has_many :loans, class_name: "Dscf::Credit::Loan", foreign_key: "payment_request_id", dependent: :destroy
|
9
|
-
has_many :payments, class_name: "Dscf::Credit::Payment", foreign_key: "payment_request_id", dependent: :destroy
|
10
|
-
|
11
|
-
validates :order_id, presence: true, uniqueness: true
|
12
|
-
validates :request_type, :amount, :receiver_account_reference, presence: true
|
13
|
-
validates :amount, numericality: { greater_than: 0 }
|
14
|
-
validates :status, inclusion: { in: %w[pending approved rejected processed failed] }
|
15
|
-
|
16
|
-
scope :pending, -> { where(status: "pending") }
|
17
|
-
scope :approved, -> { where(status: "approved") }
|
18
|
-
scope :processed, -> { where(status: "processed") }
|
19
|
-
scope :failed, -> { where(status: "failed") }
|
20
|
-
|
21
|
-
def self.ransackable_attributes(auth_object = nil)
|
22
|
-
%w[id order_id request_type amount receiver_account_reference status failure_reason initiated_at approved_at created_at updated_at]
|
23
|
-
end
|
24
|
-
|
25
|
-
def self.ransackable_associations(auth_object = nil)
|
26
|
-
%w[user loans payments]
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
@@ -1,10 +0,0 @@
|
|
1
|
-
module Dscf::Credit
|
2
|
-
class PaymentRequestSerializer < ActiveModel::Serializer
|
3
|
-
attributes :id, :order_id, :request_type, :amount, :receiver_account_reference,
|
4
|
-
:status, :failure_reason, :initiated_at, :approved_at, :created_at, :updated_at
|
5
|
-
|
6
|
-
belongs_to :user, serializer: Dscf::Core::UserSerializer
|
7
|
-
has_many :loans, serializer: Dscf::Credit::LoanSerializer
|
8
|
-
has_many :payments, serializer: Dscf::Credit::PaymentSerializer
|
9
|
-
end
|
10
|
-
end
|
@@ -1,8 +0,0 @@
|
|
1
|
-
module Dscf::Credit
|
2
|
-
class PaymentSerializer < ActiveModel::Serializer
|
3
|
-
attributes :id, :amount, :receiver_account_reference, :transaction_reference,
|
4
|
-
:status, :failure_reason, :processed_at, :created_at, :updated_at
|
5
|
-
|
6
|
-
belongs_to :payment_request, serializer: PaymentRequestSerializer
|
7
|
-
end
|
8
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
class CreateDscfCreditPaymentRequests < ActiveRecord::Migration[8.0]
|
2
|
-
def change
|
3
|
-
create_table :dscf_credit_payment_requests do |t|
|
4
|
-
t.references :user, null: false, foreign_key: { to_table: :dscf_core_users }
|
5
|
-
t.string :order_id, null: false
|
6
|
-
t.string :request_type, null: false
|
7
|
-
t.decimal :amount, precision: 15, scale: 2, null: false
|
8
|
-
t.string :receiver_account_reference, null: false
|
9
|
-
t.string :status, default: 'pending'
|
10
|
-
t.text :failure_reason
|
11
|
-
t.datetime :initiated_at
|
12
|
-
t.datetime :approved_at
|
13
|
-
|
14
|
-
t.timestamps
|
15
|
-
end
|
16
|
-
|
17
|
-
add_index :dscf_credit_payment_requests, :order_id, unique: true
|
18
|
-
add_index :dscf_credit_payment_requests, :request_type
|
19
|
-
add_index :dscf_credit_payment_requests, :status
|
20
|
-
add_index :dscf_credit_payment_requests, :receiver_account_reference
|
21
|
-
add_index :dscf_credit_payment_requests, :initiated_at
|
22
|
-
add_index :dscf_credit_payment_requests, :approved_at
|
23
|
-
add_index :dscf_credit_payment_requests, [ :user_id, :status ]
|
24
|
-
add_index :dscf_credit_payment_requests, [ :user_id, :request_type ]
|
25
|
-
end
|
26
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
class CreateDscfCreditPayments < ActiveRecord::Migration[8.0]
|
2
|
-
def change
|
3
|
-
create_table :dscf_credit_payments do |t|
|
4
|
-
t.references :payment_request, null: false, foreign_key: { to_table: :dscf_credit_payment_requests }
|
5
|
-
t.decimal :amount, precision: 15, scale: 2, null: false
|
6
|
-
t.string :receiver_account_reference, null: false
|
7
|
-
t.string :transaction_reference, null: false
|
8
|
-
t.string :status, default: 'pending'
|
9
|
-
t.text :failure_reason
|
10
|
-
t.datetime :processed_at
|
11
|
-
|
12
|
-
t.timestamps
|
13
|
-
end
|
14
|
-
|
15
|
-
add_index :dscf_credit_payments, :transaction_reference, unique: true
|
16
|
-
add_index :dscf_credit_payments, :receiver_account_reference
|
17
|
-
add_index :dscf_credit_payments, :status
|
18
|
-
add_index :dscf_credit_payments, :amount
|
19
|
-
add_index :dscf_credit_payments, :processed_at
|
20
|
-
add_index :dscf_credit_payments, [ :payment_request_id, :status ]
|
21
|
-
add_index :dscf_credit_payments, :created_at
|
22
|
-
end
|
23
|
-
end
|
@@ -1,40 +0,0 @@
|
|
1
|
-
FactoryBot.define do
|
2
|
-
factory :payment_request, class: "Dscf::Credit::PaymentRequest" do
|
3
|
-
association :user, factory: :user if defined?(Dscf::Core::User)
|
4
|
-
order_id { Faker::Alphanumeric.alphanumeric(number: 16).upcase }
|
5
|
-
request_type { %w[loan_disbursement loan_repayment interest_payment fee_payment].sample }
|
6
|
-
amount { Faker::Number.decimal(l_digits: 5, r_digits: 2) }
|
7
|
-
receiver_account_reference { Faker::Bank.account_number }
|
8
|
-
status { %w[pending approved rejected processed failed].sample }
|
9
|
-
failure_reason { Faker::Lorem.sentence if status.in?(%w[rejected failed]) }
|
10
|
-
initiated_at { Faker::Time.between(from: 1.month.ago, to: Time.current) }
|
11
|
-
approved_at { initiated_at + rand(1..24).hours if status.in?(%w[approved processed]) }
|
12
|
-
|
13
|
-
trait :pending do
|
14
|
-
status { "pending" }
|
15
|
-
approved_at { nil }
|
16
|
-
failure_reason { nil }
|
17
|
-
end
|
18
|
-
|
19
|
-
trait :approved do
|
20
|
-
status { "approved" }
|
21
|
-
approved_at { initiated_at + rand(1..24).hours }
|
22
|
-
failure_reason { nil }
|
23
|
-
end
|
24
|
-
|
25
|
-
trait :rejected do
|
26
|
-
status { "rejected" }
|
27
|
-
failure_reason { Faker::Lorem.sentence }
|
28
|
-
end
|
29
|
-
|
30
|
-
trait :processed do
|
31
|
-
status { "processed" }
|
32
|
-
approved_at { initiated_at + rand(1..24).hours }
|
33
|
-
end
|
34
|
-
|
35
|
-
trait :failed do
|
36
|
-
status { "failed" }
|
37
|
-
failure_reason { Faker::Lorem.sentence }
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
@@ -1,39 +0,0 @@
|
|
1
|
-
FactoryBot.define do
|
2
|
-
factory :payment, class: "Dscf::Credit::Payment" do
|
3
|
-
association :payment_request, factory: :payment_request
|
4
|
-
amount { Faker::Number.decimal(l_digits: 5, r_digits: 2) }
|
5
|
-
receiver_account_reference { Faker::Alphanumeric.alphanumeric(number: 20) }
|
6
|
-
transaction_reference { Faker::Alphanumeric.alphanumeric(number: 16) }
|
7
|
-
status { %w[pending processing completed failed cancelled].sample }
|
8
|
-
failure_reason { Faker::Lorem.sentence if status.in?(%w[failed cancelled]) }
|
9
|
-
processed_at { Faker::Time.between(from: 1.month.ago, to: Time.current) if status.in?(%w[completed failed]) }
|
10
|
-
|
11
|
-
trait :pending do
|
12
|
-
status { "pending" }
|
13
|
-
processed_at { nil }
|
14
|
-
failure_reason { nil }
|
15
|
-
end
|
16
|
-
|
17
|
-
trait :processing do
|
18
|
-
status { "processing" }
|
19
|
-
processed_at { nil }
|
20
|
-
end
|
21
|
-
|
22
|
-
trait :completed do
|
23
|
-
status { "completed" }
|
24
|
-
processed_at { Faker::Time.between(from: 1.month.ago, to: Time.current) }
|
25
|
-
failure_reason { nil }
|
26
|
-
end
|
27
|
-
|
28
|
-
trait :failed do
|
29
|
-
status { "failed" }
|
30
|
-
processed_at { Faker::Time.between(from: 1.month.ago, to: Time.current) }
|
31
|
-
failure_reason { Faker::Lorem.sentence }
|
32
|
-
end
|
33
|
-
|
34
|
-
trait :cancelled do
|
35
|
-
status { "cancelled" }
|
36
|
-
failure_reason { Faker::Lorem.sentence }
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|