dscf-credit 0.1.2 → 0.1.3

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.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/concerns/dscf/core/authenticatable.rb +81 -0
  3. data/app/controllers/concerns/dscf/core/common.rb +200 -0
  4. data/app/controllers/concerns/dscf/core/filterable.rb +12 -0
  5. data/app/controllers/concerns/dscf/core/json_response.rb +77 -0
  6. data/app/controllers/concerns/dscf/core/pagination.rb +71 -0
  7. data/app/controllers/concerns/dscf/core/token_authenticatable.rb +53 -0
  8. data/app/controllers/dscf/credit/categories_controller.rb +3 -3
  9. data/app/controllers/dscf/credit/credit_limit_calculations_controller.rb +50 -0
  10. data/app/controllers/dscf/credit/credit_line_specs_controller.rb +2 -1
  11. data/app/controllers/dscf/credit/credit_lines_controller.rb +3 -3
  12. data/app/controllers/dscf/credit/disbursements_controller.rb +55 -0
  13. data/app/controllers/dscf/credit/eligible_credit_lines_controller.rb +50 -0
  14. data/app/controllers/dscf/credit/loan_profiles_controller.rb +138 -0
  15. data/app/controllers/dscf/credit/payment_requests_controller.rb +54 -5
  16. data/app/controllers/dscf/credit/repayments_controller.rb +53 -0
  17. data/app/controllers/dscf/credit/scoring_parameters_controller.rb +3 -3
  18. data/app/controllers/dscf/credit/scoring_tables_controller.rb +8 -8
  19. data/app/models/dscf/credit/bank_branch.rb +2 -1
  20. data/app/models/dscf/credit/category.rb +3 -1
  21. data/app/models/dscf/credit/credit_line.rb +3 -3
  22. data/app/models/dscf/credit/credit_line_spec.rb +3 -3
  23. data/app/models/dscf/credit/eligible_credit_line.rb +28 -0
  24. data/app/models/dscf/credit/loan_profile.rb +8 -5
  25. data/app/models/dscf/credit/loan_profile_scoring_spec.rb +4 -5
  26. data/app/models/dscf/credit/scoring_parameter.rb +2 -2
  27. data/app/models/dscf/credit/scoring_table.rb +4 -4
  28. data/app/serializers/dscf/credit/bank_branch_serializer.rb +1 -0
  29. data/app/serializers/dscf/credit/category_serializer.rb +2 -0
  30. data/app/serializers/dscf/credit/credit_line_serializer.rb +2 -0
  31. data/app/serializers/dscf/credit/credit_line_spec_serializer.rb +1 -1
  32. data/app/serializers/dscf/credit/daily_routine_transaction_serializer.rb +8 -0
  33. data/app/serializers/dscf/credit/eligible_credit_line_serializer.rb +8 -0
  34. data/app/serializers/dscf/credit/loan_profile_scoring_spec_serializer.rb +8 -0
  35. data/app/serializers/dscf/credit/loan_profile_serializer.rb +15 -0
  36. data/app/serializers/dscf/credit/loan_serializer.rb +12 -0
  37. data/app/serializers/dscf/credit/loan_transaction_serializer.rb +8 -0
  38. data/app/serializers/dscf/credit/payment_request_serializer.rb +10 -0
  39. data/app/serializers/dscf/credit/payment_serializer.rb +8 -0
  40. data/app/serializers/dscf/credit/scoring_parameter_serializer.rb +2 -0
  41. data/app/serializers/dscf/credit/scoring_table_serializer.rb +1 -1
  42. data/app/services/dscf/credit/credit_limit_calculation_service.rb +153 -0
  43. data/app/services/dscf/credit/disbursement_service.rb +180 -0
  44. data/app/services/dscf/credit/repayment_service.rb +216 -0
  45. data/app/services/dscf/credit/risk_application_service.rb +27 -0
  46. data/app/services/dscf/credit/scoring_service.rb +297 -0
  47. data/config/locales/en.yml +79 -0
  48. data/config/routes.rb +19 -5
  49. data/db/migrate/20250822091527_create_dscf_credit_credit_line_specs.rb +1 -0
  50. data/db/migrate/20250822092246_create_dscf_credit_loan_profiles.rb +2 -1
  51. data/db/migrate/20250822092417_create_dscf_credit_loan_profile_scoring_specs.rb +5 -8
  52. data/db/migrate/20250901172842_create_dscf_credit_scoring_tables.rb +2 -2
  53. data/db/migrate/20250917120000_create_dscf_credit_eligible_credit_lines.rb +18 -0
  54. data/db/seeds.rb +88 -22
  55. data/lib/dscf/credit/version.rb +1 -1
  56. data/spec/factories/dscf/credit/credit_line_specs.rb +1 -0
  57. data/spec/factories/dscf/credit/credit_lines.rb +3 -3
  58. data/spec/factories/dscf/credit/eligible_credit_lines.rb +33 -0
  59. data/spec/factories/dscf/credit/loan_profile_scoring_specs.rb +1 -4
  60. data/spec/factories/dscf/credit/loan_profiles.rb +1 -0
  61. data/spec/factories/dscf/credit/scoring_tables.rb +1 -1
  62. metadata +29 -2
@@ -0,0 +1,297 @@
1
+ module Dscf::Credit
2
+ class ScoringService
3
+ attr_reader :loan_profile
4
+
5
+ def initialize(loan_profile)
6
+ @loan_profile = loan_profile
7
+ end
8
+
9
+ # Calculate credit score for a loan profile using the eligibility category scoring table
10
+ # @param external_scoring_data [Hash] Optional external scoring input data
11
+ # @return [Hash] Result containing score, total_limit, and success status
12
+ def calculate_credit_score(external_scoring_data = nil)
13
+ eligibility_category = find_eligibility_category
14
+ return error_result("Eligibility category not found") unless eligibility_category
15
+
16
+ scoring_tables = eligibility_category.scoring_tables.active.includes(:scoring_parameter)
17
+ return error_result("No active scoring parameters found for eligibility category") if scoring_tables.empty?
18
+
19
+ scoring_data = get_scoring_data(external_scoring_data)
20
+ score = calculate_weighted_score(scoring_tables, scoring_data)
21
+ facility_limit = calculate_facility_limit(score, scoring_data)
22
+
23
+ success_result(score, facility_limit)
24
+ rescue StandardError => e
25
+ error_result("Score calculation failed: #{e.message}")
26
+ end
27
+
28
+ private
29
+
30
+ def get_scoring_data(external_scoring_data)
31
+ if external_scoring_data.present?
32
+ external_scoring_data
33
+ else
34
+ extract_scoring_data_from_profile
35
+ end
36
+ end
37
+
38
+ def extract_scoring_data_from_profile
39
+ latest_spec = loan_profile.loan_profile_scoring_specs.order(created_at: :desc).first
40
+
41
+ if latest_spec&.scoring_input_data.present? && !latest_spec.scoring_input_data.empty?
42
+ default_data = prepare_scoring_data
43
+ default_data.merge(latest_spec.scoring_input_data.symbolize_keys)
44
+ else
45
+ prepare_scoring_data
46
+ end
47
+ end
48
+
49
+ def find_eligibility_category
50
+ Dscf::Credit::Category.find_by(type: "eligibility", name: "default") ||
51
+ Dscf::Credit::Category.find_by(type: "eligibility")
52
+ end
53
+
54
+ def prepare_scoring_data
55
+ {
56
+ average_daily_purchase: extract_average_daily_purchase,
57
+ years_at_location: extract_years_at_location,
58
+ marital_status: extract_marital_status,
59
+ dependents_count: extract_dependents_count,
60
+ education_level: extract_education_level,
61
+ bill_payment_timing: extract_bill_payment_timing,
62
+ other_accounts: extract_other_accounts,
63
+ money_preference: extract_money_preference,
64
+ business_license: extract_business_license,
65
+ bank_statements: extract_bank_statements,
66
+ transaction_frequency: extract_transaction_frequency,
67
+ purchase_volume: extract_purchase_volume,
68
+ cancellation_rate: extract_cancellation_rate,
69
+ reliability_score: extract_reliability_score
70
+ }
71
+ end
72
+
73
+ # Calculate weighted score based on scoring parameters
74
+ def calculate_weighted_score(scoring_tables, scoring_data)
75
+ total_score = 0.0
76
+ total_weight = 0.0
77
+
78
+ scoring_tables.each do |table|
79
+ parameter = table.scoring_parameter
80
+ raw_value = find_parameter_value(parameter, scoring_data)
81
+
82
+ next if raw_value.nil?
83
+
84
+ normalized_score = normalize_parameter_value(parameter, raw_value)
85
+ weighted_score = normalized_score * table.weight
86
+
87
+ total_score += weighted_score
88
+ total_weight += table.weight
89
+ end
90
+
91
+ return 0.0 if total_weight.zero?
92
+
93
+ (total_score / total_weight) * 100
94
+ end
95
+
96
+ # Find parameter value from scoring data using flexible key matching
97
+ def find_parameter_value(parameter, scoring_data)
98
+ param_name = parameter.name
99
+
100
+ # Try exact match first
101
+ if scoring_data.key?(param_name.to_sym)
102
+ return scoring_data[param_name.to_sym]
103
+ end
104
+
105
+ if scoring_data.key?(param_name)
106
+ return scoring_data[param_name]
107
+ end
108
+
109
+ # Try snake_case version
110
+ snake_case_name = param_name.downcase.gsub(/\s+/, "_")
111
+ if scoring_data.key?(snake_case_name.to_sym)
112
+ return scoring_data[snake_case_name.to_sym]
113
+ end
114
+
115
+ if scoring_data.key?(snake_case_name)
116
+ return scoring_data[snake_case_name]
117
+ end
118
+
119
+ # Try common mappings
120
+ case param_name.downcase
121
+ when "monthly income"
122
+ scoring_data[:monthly_income] || scoring_data["monthly_income"]
123
+ when "credit history score"
124
+ scoring_data[:credit_history_score] || scoring_data["credit_history_score"]
125
+ when "employment type"
126
+ scoring_data[:employment_type] || scoring_data["employment_type"]
127
+ else
128
+ nil
129
+ end
130
+ end
131
+
132
+ # Calculate facility limit based on score and business metrics
133
+ def calculate_facility_limit(score, scoring_data)
134
+ return 0 if score < 50 # Below 50% score = no facility
135
+
136
+ average_daily_purchase = scoring_data[:average_daily_purchase] || 0
137
+
138
+ credit_line_multiplier = get_default_credit_line_multiplier
139
+
140
+ base_limit = average_daily_purchase * credit_line_multiplier * (score / 100.0)
141
+
142
+ apply_limit_constraints(base_limit)
143
+ end
144
+
145
+ # Get default credit line multiplier from the bank's approved credit line specs
146
+ def get_default_credit_line_multiplier
147
+ return 30.0 unless loan_profile.bank
148
+
149
+ credit_line_spec = loan_profile.bank.credit_lines.approved
150
+ .joins(:credit_line_specs)
151
+ .merge(Dscf::Credit::CreditLineSpec.active)
152
+ .select("dscf_credit_credit_line_specs.credit_line_multiplier")
153
+ .first&.credit_line_specs&.active&.first
154
+
155
+ credit_line_spec&.credit_line_multiplier || 30.0
156
+ end
157
+
158
+ def apply_limit_constraints(base_limit)
159
+ min_limit = get_bank_config("min_credit_limit", 0)
160
+ max_limit = get_bank_config("max_credit_limit", 1000000)
161
+
162
+ return 0 if base_limit < min_limit
163
+ return max_limit if base_limit > max_limit
164
+
165
+ base_limit
166
+ end
167
+
168
+ # Get bank configuration value from system configs
169
+ def get_bank_config(config_key, default_value)
170
+ return default_value unless loan_profile.bank
171
+
172
+ config_definition = loan_profile.bank.system_config_definitions
173
+ .find_by(config_key: config_key)
174
+ return default_value unless config_definition
175
+
176
+ system_config = Dscf::Credit::SystemConfig.approved
177
+ .find_by(config_definition: config_definition)
178
+
179
+ if system_config&.config_value
180
+ numeric_value = system_config.config_value.to_f
181
+ numeric_value > 0 ? numeric_value : default_value
182
+ else
183
+ default_value
184
+ end
185
+ end
186
+
187
+ # Normalize parameter value to 0-1 scale
188
+ def normalize_parameter_value(parameter, raw_value)
189
+ case parameter.data_type
190
+ when "boolean"
191
+ raw_value ? 1.0 : 0.0
192
+ when "integer", "decimal"
193
+ normalize_numeric_value(parameter, raw_value.to_f)
194
+ when "string"
195
+ normalize_string_value(parameter, raw_value)
196
+ else
197
+ 0.5 # Default neutral score
198
+ end
199
+ end
200
+
201
+ def normalize_numeric_value(parameter, value)
202
+ min_val = parameter.min_value || 0
203
+ max_val = parameter.max_value || 100
204
+
205
+ return 0.0 if value < min_val
206
+ return 1.0 if value > max_val
207
+
208
+ (value - min_val) / (max_val - min_val)
209
+ end
210
+
211
+ def normalize_string_value(parameter, value)
212
+ normalizer = parameter.parameter_normalizers.find { |n| n.raw_value == value }
213
+ return normalizer.normalized_value if normalizer
214
+
215
+ case value.downcase
216
+ when "excellent", "high", "good" then 1.0
217
+ when "fair", "medium", "average" then 0.7
218
+ when "poor", "low", "bad" then 0.3
219
+ else 0.5
220
+ end
221
+ end
222
+
223
+ def extract_average_daily_purchase
224
+ 5000.0 # Default average daily purchase
225
+ end
226
+
227
+ def extract_years_at_location
228
+ 2 # Default years at current location
229
+ end
230
+
231
+ def extract_marital_status
232
+ "single" # Default marital status
233
+ end
234
+
235
+ def extract_dependents_count
236
+ 0 # Default number of dependents
237
+ end
238
+
239
+ def extract_education_level
240
+ "bachelor" # Default education level
241
+ end
242
+
243
+ def extract_bill_payment_timing
244
+ "on_time" # Default payment timing
245
+ end
246
+
247
+ def extract_other_accounts
248
+ false # Default: no other active accounts
249
+ end
250
+
251
+ def extract_money_preference
252
+ "save" # Default money preference
253
+ end
254
+
255
+ def extract_business_license
256
+ false # Default: no business license
257
+ end
258
+
259
+ def extract_bank_statements
260
+ true # Default: bank statements available
261
+ end
262
+
263
+ def extract_transaction_frequency
264
+ 15 # Default monthly transaction frequency
265
+ end
266
+
267
+ def extract_purchase_volume
268
+ 50000.0 # Default monthly purchase volume
269
+ end
270
+
271
+ def extract_cancellation_rate
272
+ 0.05 # Default 5% cancellation rate
273
+ end
274
+
275
+ def extract_reliability_score
276
+ 75.0 # Default reliability score (0-100)
277
+ end
278
+
279
+ def success_result(score, facility_limit)
280
+ {
281
+ success: true,
282
+ score: score.round(2),
283
+ facility_limit: facility_limit.round(2),
284
+ message: "Credit score calculated successfully"
285
+ }
286
+ end
287
+
288
+ def error_result(message)
289
+ {
290
+ success: false,
291
+ score: 0,
292
+ facility_limit: 0,
293
+ error: message
294
+ }
295
+ end
296
+ end
297
+ end
@@ -77,6 +77,25 @@ en:
77
77
  resubmit: "Failed to resubmit scoring parameter"
78
78
  destroy: "Failed to delete scoring parameter"
79
79
 
80
+ loan_profile:
81
+ success:
82
+ index: "Loan profiles retrieved successfully"
83
+ show: "Loan profile details retrieved successfully"
84
+ create: "Loan profile created successfully"
85
+ update: "Loan profile updated successfully"
86
+ approve: "Loan profile approved successfully"
87
+ reject: "Loan profile rejected successfully"
88
+ calculate_score: "Credit score calculated successfully"
89
+ errors:
90
+ index: "Failed to retrieve loan profiles"
91
+ show: "Failed to retrieve loan profile details"
92
+ create: "Failed to create loan profile"
93
+ update: "Failed to update loan profile"
94
+ approve: "Failed to approve loan profile"
95
+ reject: "Failed to reject loan profile"
96
+ calculate_score: "Failed to calculate credit score"
97
+ not_found: "Loan profile not found"
98
+
80
99
  parameter_normalizer:
81
100
  success:
82
101
  index: "Parameter normalizers retrieved successfully"
@@ -157,6 +176,20 @@ en:
157
176
  request_modification: "Failed to request modification"
158
177
  resubmit: "Failed to resubmit credit line"
159
178
 
179
+ eligible_credit_line:
180
+ success:
181
+ index: "Eligible credit lines retrieved successfully"
182
+ show: "Eligible credit line details retrieved successfully"
183
+ create: "Eligible credit line created successfully"
184
+ update: "Eligible credit line updated successfully"
185
+ apply_risk: "Risk applied successfully"
186
+ errors:
187
+ index: "Failed to retrieve eligible credit lines"
188
+ show: "Failed to retrieve eligible credit line details"
189
+ create: "Failed to create eligible credit line"
190
+ update: "Failed to update eligible credit line"
191
+ apply_risk: "Failed to apply risk"
192
+
160
193
  system_config_definition:
161
194
  success:
162
195
  index: "System config definitions retrieved successfully"
@@ -225,6 +258,24 @@ en:
225
258
  deactivate: "Failed to deactivate scoring table"
226
259
  destroy: "Failed to delete scoring table"
227
260
 
261
+ payment_request:
262
+ success:
263
+ index: "Payment requests retrieved successfully"
264
+ show: "Payment request details retrieved successfully"
265
+ create: "Payment request created successfully"
266
+ update: "Payment request updated successfully"
267
+ approve: "Payment request approved successfully"
268
+ eligible_credit_lines: "Eligible credit lines retrieved successfully"
269
+ destroy: "Payment request deleted successfully"
270
+ errors:
271
+ index: "Failed to retrieve payment requests"
272
+ show: "Failed to retrieve payment request details"
273
+ create: "Failed to create payment request"
274
+ update: "Failed to update payment request"
275
+ approve: "Failed to approve payment request"
276
+ eligible_credit_lines: "Failed to retrieve eligible credit lines"
277
+ destroy: "Failed to delete payment request"
278
+
228
279
  # Global messages
229
280
  operations:
230
281
  success:
@@ -234,6 +285,34 @@ en:
234
285
  failed: "Operation failed"
235
286
  not_found: "Resource not found"
236
287
 
288
+ loan_profile:
289
+ success:
290
+ calculate_score: "Credit score calculated successfully"
291
+ errors:
292
+ calculate_score: "Failed to calculate credit score"
293
+ not_found: "Loan profile not found"
294
+
295
+ credit_limit_calculation:
296
+ success:
297
+ create: "Credit limits calculated successfully"
298
+ errors:
299
+ create: "Failed to calculate credit limits"
300
+ not_found: "Loan profile or category not found"
301
+
302
+ disbursement:
303
+ success:
304
+ create: "Disbursement processed successfully"
305
+ errors:
306
+ create: "Failed to process disbursement"
307
+ not_found: "Credit line or payment request not found"
308
+
309
+ repayment:
310
+ success:
311
+ create: "Repayment processed successfully"
312
+ errors:
313
+ create: "Failed to process repayment"
314
+ not_found: "Loan not found"
315
+
237
316
  errors:
238
317
  validation_failed: "Validation failed"
239
318
  access_denied: "Access denied"
data/config/routes.rb CHANGED
@@ -19,14 +19,19 @@ Dscf::Credit::Engine.routes.draw do
19
19
  end
20
20
  end
21
21
 
22
- resources :loan_profiles, only: [ :index, :show, :create, :update, :destroy ] do
22
+ resources :loan_profiles do
23
23
  member do
24
- get "kyc_review", to: "kyc_reviews#show"
25
- patch "kyc_review", to: "kyc_reviews#update"
24
+ patch "approve"
25
+ patch "reject"
26
+ post "calculate_score"
27
+ end
28
+ end
29
+ resources :payment_requests do
30
+ member do
31
+ patch "approve"
32
+ get "eligible_credit_lines"
26
33
  end
27
34
  end
28
-
29
- resources :payment_requests
30
35
  resources :scoring_parameters do
31
36
  member do
32
37
  patch "approve"
@@ -54,6 +59,11 @@ Dscf::Credit::Engine.routes.draw do
54
59
  end
55
60
  end
56
61
  resources :credit_line_specs
62
+ resources :eligible_credit_lines do
63
+ member do
64
+ patch "apply_risk", to: "eligible_credit_lines#apply_risk"
65
+ end
66
+ end
57
67
  resources :categories
58
68
  resources :scoring_tables do
59
69
  member do
@@ -64,4 +74,8 @@ Dscf::Credit::Engine.routes.draw do
64
74
  resources :users
65
75
  resources :kyc_reviews, only: [ :index, :show ]
66
76
  resources :bank_staffs
77
+
78
+ resources :credit_limit_calculations, only: [ :create ]
79
+ resources :disbursements, only: [ :create ]
80
+ resources :repayments, only: [ :create ]
67
81
  end
@@ -8,6 +8,7 @@ class CreateDscfCreditCreditLineSpecs < ActiveRecord::Migration[8.0]
8
8
  t.decimal :penalty_rate, precision: 5, scale: 4, null: false
9
9
  t.decimal :facilitation_fee_rate, precision: 5, scale: 4, null: false
10
10
  t.decimal :tax_rate, precision: 5, scale: 4, null: false
11
+ t.decimal :credit_line_multiplier, precision: 5, scale: 2, null: false, default: 30.0
11
12
  t.integer :max_penalty_days, null: false
12
13
  t.integer :loan_duration, null: false
13
14
  t.string :interest_frequency, null: false
@@ -7,9 +7,10 @@ class CreateDscfCreditLoanProfiles < ActiveRecord::Migration[8.0]
7
7
  t.string :status, default: 'pending'
8
8
  t.decimal :total_amount, precision: 15, scale: 2, default: 0
9
9
  t.decimal :available_amount, precision: 15, scale: 2, default: 0
10
- t.references :reviewed_by, polymorphic: true, null: false
10
+ t.references :reviewed_by, polymorphic: true
11
11
  t.datetime :review_date
12
12
  t.jsonb :review_feedback, default: {}
13
+ t.references :review_branch, null: true, foreign_key: { to_table: :dscf_credit_bank_branches }
13
14
 
14
15
  t.timestamps
15
16
  end
@@ -2,22 +2,19 @@ class CreateDscfCreditLoanProfileScoringSpecs < ActiveRecord::Migration[8.0]
2
2
  def change
3
3
  create_table :dscf_credit_loan_profile_scoring_specs do |t|
4
4
  t.references :loan_profile, null: false, foreign_key: { to_table: :dscf_credit_loan_profiles }
5
- t.jsonb :scoring_input_data, null: false
6
- t.decimal :score, precision: 5, scale: 2, null: false
5
+ t.jsonb :scoring_input_data
6
+ t.decimal :score, precision: 5, scale: 2
7
+ t.decimal :total_limit, precision: 15, scale: 2
7
8
  t.boolean :active, default: true
8
- t.references :created_by, polymorphic: true, null: false
9
- t.references :reviewed_by, polymorphic: true, null: false
10
- t.datetime :review_date
11
- t.jsonb :review_feedback, default: {}
9
+ t.references :created_by, polymorphic: true
12
10
 
13
11
  t.timestamps
14
12
  end
15
13
 
16
14
  add_index :dscf_credit_loan_profile_scoring_specs, :score
15
+ add_index :dscf_credit_loan_profile_scoring_specs, :total_limit
17
16
  add_index :dscf_credit_loan_profile_scoring_specs, :active
18
17
  add_index :dscf_credit_loan_profile_scoring_specs, [ :created_by_type, :created_by_id ]
19
- add_index :dscf_credit_loan_profile_scoring_specs, [ :reviewed_by_type, :reviewed_by_id ]
20
- add_index :dscf_credit_loan_profile_scoring_specs, :review_date
21
18
  add_index :dscf_credit_loan_profile_scoring_specs, :scoring_input_data, using: :gin
22
19
  add_index :dscf_credit_loan_profile_scoring_specs, [ :loan_profile_id, :active ]
23
20
  end
@@ -1,7 +1,7 @@
1
1
  class CreateDscfCreditScoringTables < ActiveRecord::Migration[8.0]
2
2
  def change
3
3
  create_table :dscf_credit_scoring_tables do |t|
4
- t.references :credit_line, null: false, foreign_key: { to_table: :dscf_credit_credit_lines }
4
+ t.references :category, null: false, foreign_key: { to_table: :dscf_credit_categories }
5
5
  t.references :scoring_parameter, null: false, foreign_key: { to_table: :dscf_credit_scoring_parameters }
6
6
  t.decimal :weight, precision: 5, scale: 4, null: false
7
7
  t.boolean :active, default: true
@@ -13,6 +13,6 @@ class CreateDscfCreditScoringTables < ActiveRecord::Migration[8.0]
13
13
  add_index :dscf_credit_scoring_tables, :weight
14
14
  add_index :dscf_credit_scoring_tables, :active
15
15
  add_index :dscf_credit_scoring_tables, [ :created_by_type, :created_by_id ]
16
- add_index :dscf_credit_scoring_tables, [ :credit_line_id, :scoring_parameter_id ], unique: true, name: 'index_scoring_tables_on_credit_line_and_scoring_parameter'
16
+ add_index :dscf_credit_scoring_tables, [ :category_id, :scoring_parameter_id ], unique: true, name: 'index_scoring_tables_on_category_and_scoring_parameter'
17
17
  end
18
18
  end
@@ -0,0 +1,18 @@
1
+ class CreateDscfCreditEligibleCreditLines < ActiveRecord::Migration[8.0]
2
+ def change
3
+ create_table :dscf_credit_eligible_credit_lines do |t|
4
+ t.references :loan_profile, null: false, foreign_key: { to_table: :dscf_credit_loan_profiles }
5
+ t.references :credit_line, null: false, foreign_key: { to_table: :dscf_credit_credit_lines }
6
+ t.decimal :credit_limit, precision: 15, scale: 2, null: false
7
+ t.decimal :available_limit, precision: 15, scale: 2, null: false
8
+ t.decimal :risk, precision: 5, scale: 4, null: true
9
+
10
+ t.timestamps
11
+ end
12
+
13
+ add_index :dscf_credit_eligible_credit_lines, [ :loan_profile_id, :credit_line_id ]
14
+ add_index :dscf_credit_eligible_credit_lines, :credit_limit
15
+ add_index :dscf_credit_eligible_credit_lines, :available_limit
16
+ add_index :dscf_credit_eligible_credit_lines, :risk
17
+ end
18
+ end