dscf-credit 0.1.1 → 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.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/concerns/dscf/credit/reviewable.rb +112 -0
  3. data/app/controllers/dscf/credit/categories_controller.rb +3 -2
  4. data/app/controllers/dscf/credit/credit_lines_controller.rb +11 -38
  5. data/app/controllers/dscf/credit/facilitators_controller.rb +39 -150
  6. data/app/controllers/dscf/credit/scoring_param_types_controller.rb +31 -0
  7. data/app/controllers/dscf/credit/scoring_parameters_controller.rb +13 -8
  8. data/app/controllers/dscf/credit/system_configs_controller.rb +10 -7
  9. data/app/models/dscf/credit/category.rb +1 -1
  10. data/app/models/dscf/credit/credit_line.rb +7 -4
  11. data/app/models/dscf/credit/facilitator.rb +5 -4
  12. data/app/models/dscf/credit/facilitator_performance.rb +1 -2
  13. data/app/models/dscf/credit/loan_profile.rb +4 -3
  14. data/app/models/dscf/credit/loan_profile_scoring_spec.rb +3 -4
  15. data/app/models/dscf/credit/scoring_param_type.rb +17 -0
  16. data/app/models/dscf/credit/scoring_parameter.rb +7 -6
  17. data/app/models/dscf/credit/system_config.rb +5 -4
  18. data/app/serializers/dscf/credit/category_serializer.rb +1 -1
  19. data/app/serializers/dscf/credit/credit_line_serializer.rb +2 -2
  20. data/app/serializers/dscf/credit/facilitator_performance_serializer.rb +1 -1
  21. data/app/serializers/dscf/credit/facilitator_serializer.rb +2 -2
  22. data/app/serializers/dscf/credit/scoring_param_type_serializer.rb +7 -0
  23. data/app/serializers/dscf/credit/scoring_parameter_serializer.rb +4 -3
  24. data/app/serializers/dscf/credit/system_config_serializer.rb +2 -2
  25. data/app/services/dscf/credit/facilitator_approval_service.rb +4 -3
  26. data/app/services/dscf/credit/facilitator_creation_service.rb +157 -0
  27. data/config/locales/en.yml +46 -8
  28. data/config/routes.rb +23 -6
  29. data/db/migrate/20250822091011_create_dscf_credit_categories.rb +2 -0
  30. data/db/migrate/20250822091131_create_dscf_credit_credit_lines.rb +7 -4
  31. data/db/migrate/20250822091820_create_dscf_credit_system_configs.rb +5 -2
  32. data/db/migrate/20250822092040_create_dscf_credit_scoring_param_types.rb +12 -0
  33. data/db/migrate/20250822092050_create_dscf_credit_scoring_parameters.rb +11 -6
  34. data/db/migrate/20250822092246_create_dscf_credit_loan_profiles.rb +5 -3
  35. data/db/migrate/20250822092417_create_dscf_credit_loan_profile_scoring_specs.rb +5 -4
  36. data/db/migrate/20250822092436_create_dscf_credit_facilitators.rb +5 -2
  37. data/db/migrate/20250822092528_create_dscf_credit_facilitator_performances.rb +0 -3
  38. data/db/seeds.rb +48 -20
  39. data/lib/dscf/credit/version.rb +1 -1
  40. data/spec/factories/dscf/credit/categories.rb +1 -0
  41. data/spec/factories/dscf/credit/credit_lines.rb +7 -5
  42. data/spec/factories/dscf/credit/facilitator_performances.rb +0 -5
  43. data/spec/factories/dscf/credit/facilitators.rb +6 -1
  44. data/spec/factories/dscf/credit/loan_profile_scoring_specs.rb +3 -6
  45. data/spec/factories/dscf/credit/loan_profiles.rb +10 -6
  46. data/spec/factories/dscf/credit/scoring_param_types.rb +31 -0
  47. data/spec/factories/dscf/credit/scoring_parameters.rb +26 -4
  48. data/spec/factories/dscf/credit/system_configs.rb +8 -2
  49. metadata +23 -2
@@ -4,7 +4,7 @@ module Dscf::Credit
4
4
  self.inheritance_column = nil # Disable STI since 'type' is a business attribute
5
5
 
6
6
  belongs_to :bank, class_name: "Dscf::Credit::Bank", foreign_key: "bank_id"
7
- belongs_to :kyc_approved_by, polymorphic: true
7
+ belongs_to :kyc_reviewed_by, polymorphic: true
8
8
  if defined?(Dscf::Core::User)
9
9
  belongs_to :user, class_name: "Dscf::Core::User", foreign_key: "user_id"
10
10
  end
@@ -12,20 +12,21 @@ module Dscf::Credit
12
12
 
13
13
  validates :name, :type, presence: true
14
14
  validates :type, inclusion: { in: %w[individual corporate agent] }
15
- validates :kyc_status, inclusion: { in: %w[pending approved rejected] }
16
15
  validates :user_id, uniqueness: { scope: :bank_id }
17
16
  validates :total_limit, numericality: { greater_than_or_equal_to: 0 }, allow_nil: true
18
17
 
18
+ enum :kyc_status, { pending: "pending", approved: "approved", rejected: "rejected" }
19
+
19
20
  scope :approved, -> { where(kyc_status: "approved") }
20
21
  scope :pending_kyc, -> { where(kyc_status: "pending") }
21
22
  scope :rejected, -> { where(kyc_status: "rejected") }
22
23
 
23
24
  def self.ransackable_attributes(auth_object = nil)
24
- %w[id name type total_limit kyc_status created_at updated_at]
25
+ %w[id name type total_limit kyc_status kyc_review_date review_feedback created_at updated_at]
25
26
  end
26
27
 
27
28
  def self.ransackable_associations(auth_object = nil)
28
- %w[bank user kyc_approved_by facilitator_performances]
29
+ %w[bank user kyc_reviewed_by facilitator_performances]
29
30
  end
30
31
  end
31
32
  end
@@ -11,7 +11,6 @@ module Dscf::Credit
11
11
  validates :score, numericality: { greater_than_or_equal_to: 0 }, allow_nil: true
12
12
 
13
13
  scope :requiring_approval, -> { where(approval_required: true) }
14
- scope :expired, -> { where("expires_at < ?", Time.current) }
15
- scope :current, -> { where("expires_at IS NULL OR expires_at > ?", Time.current) }
14
+ scope :current, -> { where("created_at > ?", 30.days.ago) } # Assuming current means recent
16
15
  end
17
16
  end
@@ -3,7 +3,7 @@ module Dscf::Credit
3
3
  self.table_name = "dscf_credit_loan_profiles"
4
4
 
5
5
  belongs_to :bank, class_name: "Dscf::Credit::Bank", foreign_key: "bank_id"
6
- belongs_to :approved_by, polymorphic: true
6
+ belongs_to :reviewed_by, polymorphic: true
7
7
  belongs_to :backer, polymorphic: true, optional: true
8
8
  if defined?(Dscf::Core::User)
9
9
  belongs_to :user, class_name: "Dscf::Core::User", foreign_key: "user_id"
@@ -12,6 +12,7 @@ module Dscf::Credit
12
12
  has_many :loans, class_name: "Dscf::Credit::Loan", foreign_key: "loan_profile_id", dependent: :destroy
13
13
 
14
14
  validates :status, inclusion: { in: %w[pending approved rejected kyc_approved kyc_rejected] }
15
+ enum :status, { pending: "pending", approved: "approved", rejected: "rejected", kyc_approved: "kyc_approved", kyc_rejected: "kyc_rejected" }
15
16
  validates :total_amount, :available_amount, numericality: { greater_than_or_equal_to: 0 }
16
17
  validate :available_amount_not_greater_than_total_amount
17
18
 
@@ -25,11 +26,11 @@ module Dscf::Credit
25
26
  scope :by_available_amount_range, ->(min, max) { where(available_amount: min..max) }
26
27
 
27
28
  def self.ransackable_attributes(auth_object = nil)
28
- %w[id status total_amount available_amount rejection_reason created_at updated_at reviewed_by_type reviewed_by_id]
29
+ %w[id status total_amount available_amount review_feedback review_date created_at updated_at reviewed_by_type reviewed_by_id]
29
30
  end
30
31
 
31
32
  def self.ransackable_associations(auth_object = nil)
32
- %w[bank user backer approved_by reviewed_by loan_profile_scoring_specs loans]
33
+ %w[bank user backer reviewed_by loan_profile_scoring_specs loans]
33
34
  end
34
35
 
35
36
  private
@@ -4,20 +4,19 @@ 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 :created_by, polymorphic: true
7
- belongs_to :approved_by, polymorphic: true
7
+ belongs_to :reviewed_by, polymorphic: true
8
8
 
9
9
  validates :scoring_input_data, :score, presence: true
10
10
  validates :score, numericality: { greater_than_or_equal_to: 0 }
11
11
 
12
12
  scope :active, -> { where(active: true) }
13
- scope :expired, -> { where("expires_at < ?", Time.current) }
14
13
 
15
14
  def self.ransackable_attributes(auth_object = nil)
16
- %w[id score active expires_at created_at updated_at]
15
+ %w[id score active review_date review_feedback created_at updated_at]
17
16
  end
18
17
 
19
18
  def self.ransackable_associations(auth_object = nil)
20
- %w[loan_profile created_by approved_by]
19
+ %w[loan_profile created_by reviewed_by]
21
20
  end
22
21
  end
23
22
  end
@@ -0,0 +1,17 @@
1
+ module Dscf::Credit
2
+ class ScoringParamType < ApplicationRecord
3
+ self.table_name = "dscf_credit_scoring_param_types"
4
+
5
+ has_many :scoring_parameters, class_name: "Dscf::Credit::ScoringParameter", foreign_key: "scoring_param_type_id", dependent: :restrict_with_error
6
+
7
+ validates :name, presence: true, uniqueness: true
8
+
9
+ def self.ransackable_attributes(auth_object = nil)
10
+ %w[id name description created_at updated_at]
11
+ end
12
+
13
+ def self.ransackable_associations(auth_object = nil)
14
+ %w[scoring_parameters]
15
+ end
16
+ end
17
+ end
@@ -1,30 +1,31 @@
1
1
  module Dscf::Credit
2
2
  class ScoringParameter < ApplicationRecord
3
3
  self.table_name = "dscf_credit_scoring_parameters"
4
- self.inheritance_column = nil # Disable STI since 'type' is a business attribute
5
4
 
6
5
  belongs_to :bank, class_name: "Dscf::Credit::Bank", foreign_key: "bank_id"
7
6
  belongs_to :created_by, polymorphic: true
8
- belongs_to :approved_by, polymorphic: true
7
+ belongs_to :reviewed_by, polymorphic: true
8
+ belongs_to :scoring_param_type, class_name: "Dscf::Credit::ScoringParamType", foreign_key: "scoring_param_type_id"
9
9
  belongs_to :previous_version, class_name: "Dscf::Credit::ScoringParameter", optional: true
10
10
  has_many :parameter_normalizers, class_name: "Dscf::Credit::ParameterNormalizer", foreign_key: "scoring_parameter_id", dependent: :destroy
11
11
  has_many :scoring_tables, class_name: "Dscf::Credit::ScoringTable", foreign_key: "scoring_parameter_id", dependent: :destroy
12
12
  has_many :credit_lines, through: :scoring_tables
13
13
 
14
- validates :name, :data_type, :type, :weight, presence: true
14
+ validates :name, :data_type, :weight, presence: true
15
15
  validates :weight, numericality: { greater_than: 0, less_than_or_equal_to: 1 }
16
16
  validates :data_type, inclusion: { in: %w[integer decimal boolean string] }
17
- validates :type, inclusion: { in: %w[income credit_history employment_status collateral] }
18
17
  validates :name, uniqueness: { scope: [ :bank_id, :active ] }
18
+ validates :status, inclusion: { in: %w[pending approved rejected modify] }
19
+ enum :status, { pending: "pending", approved: "approved", rejected: "rejected", modify: "modify" }
19
20
 
20
21
  scope :active, -> { where(active: true) }
21
22
 
22
23
  def self.ransackable_attributes(auth_object = nil)
23
- %w[id name description data_type type weight min_value max_value active expires_at created_at updated_at]
24
+ %w[id name description data_type weight min_value max_value active status review_date review_feedback source document_reference created_at updated_at]
24
25
  end
25
26
 
26
27
  def self.ransackable_associations(auth_object = nil)
27
- %w[bank created_by approved_by previous_version parameter_normalizers scoring_tables credit_lines]
28
+ %w[bank created_by reviewed_by scoring_param_type previous_version parameter_normalizers scoring_tables credit_lines]
28
29
  end
29
30
  end
30
31
  end
@@ -4,10 +4,11 @@ module Dscf::Credit
4
4
 
5
5
  belongs_to :config_definition, class_name: "Dscf::Credit::SystemConfigDefinition", foreign_key: "config_definition_id"
6
6
  belongs_to :last_updated_by, polymorphic: true
7
- belongs_to :approved_by, polymorphic: true
7
+ belongs_to :reviewed_by, polymorphic: true
8
8
 
9
9
  validates :config_value, presence: true
10
- validates :status, inclusion: { in: %w[pending approved rejected] }
10
+ validates :status, inclusion: { in: %w[pending approved rejected modify] }
11
+ enum :status, { pending: "pending", approved: "approved", rejected: "rejected", modify: "modify" }
11
12
  validates :config_definition_id, uniqueness: true
12
13
 
13
14
  scope :pending, -> { where(status: "pending") }
@@ -15,11 +16,11 @@ module Dscf::Credit
15
16
  scope :rejected, -> { where(status: "rejected") }
16
17
 
17
18
  def self.ransackable_attributes(auth_object = nil)
18
- %w[id config_value status created_at updated_at]
19
+ %w[id config_value status review_date review_feedback created_at updated_at]
19
20
  end
20
21
 
21
22
  def self.ransackable_associations(auth_object = nil)
22
- %w[config_definition last_updated_by approved_by]
23
+ %w[config_definition last_updated_by reviewed_by]
23
24
  end
24
25
  end
25
26
  end
@@ -1,6 +1,6 @@
1
1
  module Dscf::Credit
2
2
  class CategorySerializer < ActiveModel::Serializer
3
- attributes :id, :type, :name, :description, :created_at, :updated_at
3
+ attributes :id, :type, :name, :description, :document_reference, :created_at, :updated_at
4
4
 
5
5
  has_many :credit_lines, serializer: Dscf::Credit::CreditLineSerializer
6
6
  end
@@ -1,12 +1,12 @@
1
1
  module Dscf::Credit
2
2
  class CreditLineSerializer < ActiveModel::Serializer
3
- attributes :id, :name, :code, :description, :status, :approval_date,
3
+ attributes :id, :name, :code, :description, :status, :review_date, :review_feedback, :document_reference,
4
4
  :created_at, :updated_at
5
5
 
6
6
  belongs_to :bank, serializer: Dscf::Credit::BankSerializer
7
7
  belongs_to :category, serializer: Dscf::Credit::CategorySerializer
8
8
  belongs_to :created_by, serializer: Dscf::Core::UserSerializer
9
- belongs_to :approved_by, serializer: Dscf::Core::UserSerializer
9
+ belongs_to :reviewed_by, serializer: Dscf::Core::UserSerializer
10
10
  has_many :credit_line_specs, serializer: Dscf::Credit::CreditLineSpecSerializer
11
11
  end
12
12
  end
@@ -2,7 +2,7 @@ module Dscf::Credit
2
2
  class FacilitatorPerformanceSerializer < ActiveModel::Serializer
3
3
  attributes :id, :score, :total_outstanding_loans, :total_outstanding_amount,
4
4
  :approval_required, :previous_performance_id, :input_data,
5
- :expires_at, :created_at, :updated_at
5
+ :created_at, :updated_at
6
6
 
7
7
  belongs_to :facilitator, serializer: Dscf::Credit::FacilitatorSerializer
8
8
  belongs_to :created_by, polymorphic: true
@@ -1,11 +1,11 @@
1
1
  module Dscf::Credit
2
2
  class FacilitatorSerializer < ActiveModel::Serializer
3
- attributes :id, :name, :type, :total_limit, :kyc_status,
3
+ attributes :id, :name, :type, :total_limit, :kyc_status, :kyc_review_date, :review_feedback,
4
4
  :created_at, :updated_at
5
5
 
6
6
  belongs_to :user, serializer: Dscf::Core::UserSerializer
7
7
  belongs_to :bank, serializer: Dscf::Credit::BankSerializer
8
- belongs_to :kyc_approved_by, polymorphic: true
8
+ belongs_to :kyc_reviewed_by, polymorphic: true
9
9
  has_many :facilitator_performances, serializer: Dscf::Credit::FacilitatorPerformanceSerializer
10
10
  end
11
11
  end
@@ -0,0 +1,7 @@
1
+ module Dscf::Credit
2
+ class ScoringParamTypeSerializer < ActiveModel::Serializer
3
+ attributes :id, :name, :description, :created_at, :updated_at
4
+
5
+ has_many :scoring_parameters, serializer: Dscf::Credit::ScoringParameterSerializer
6
+ end
7
+ end
@@ -1,11 +1,12 @@
1
1
  module Dscf::Credit
2
2
  class ScoringParameterSerializer < ActiveModel::Serializer
3
- attributes :id, :name, :description, :data_type, :type, :weight, :min_value,
4
- :max_value, :active, :expires_at, :created_at, :updated_at
3
+ attributes :id, :name, :description, :data_type, :weight, :min_value,
4
+ :max_value, :active, :status, :review_date, :review_feedback, :source, :document_reference, :created_at, :updated_at
5
5
 
6
6
  belongs_to :bank, serializer: Dscf::Credit::BankSerializer
7
7
  belongs_to :created_by, polymorphic: true
8
- belongs_to :approved_by, polymorphic: true
8
+ belongs_to :reviewed_by, polymorphic: true
9
+ belongs_to :scoring_param_type, serializer: Dscf::Credit::ScoringParamTypeSerializer
9
10
  belongs_to :previous_version, serializer: Dscf::Credit::ScoringParameterSerializer
10
11
  has_many :parameter_normalizers, serializer: Dscf::Credit::ParameterNormalizerSerializer
11
12
  end
@@ -1,6 +1,6 @@
1
1
  module Dscf::Credit
2
2
  class SystemConfigSerializer < ActiveModel::Serializer
3
- attributes :id, :config_value, :status, :created_at, :updated_at
3
+ attributes :id, :config_value, :status, :review_date, :review_feedback, :created_at, :updated_at
4
4
 
5
5
  attribute :config_definition do
6
6
  {
@@ -13,6 +13,6 @@ module Dscf::Credit
13
13
  end
14
14
 
15
15
  belongs_to :last_updated_by, serializer: Dscf::Core::UserSerializer
16
- belongs_to :approved_by, serializer: Dscf::Core::UserSerializer
16
+ belongs_to :reviewed_by, serializer: Dscf::Core::UserSerializer
17
17
  end
18
18
  end
@@ -29,15 +29,16 @@ module Dscf::Credit
29
29
  end
30
30
  end
31
31
 
32
- def reject(rejection_reason = nil)
32
+ def reject(review_feedback = nil)
33
33
  ActiveRecord::Base.transaction do
34
34
  facilitator.update!(
35
35
  kyc_status: "rejected",
36
- kyc_approved_by: approver
36
+ kyc_approved_by: approver,
37
+ review_feedback: review_feedback
37
38
  )
38
39
 
39
40
  begin
40
- FacilitatorMailer.rejection_notification(facilitator, rejection_reason).deliver_now
41
+ FacilitatorMailer.rejection_notification(facilitator, review_feedback).deliver_now
41
42
  rescue => e
42
43
  Rails.logger.error "Failed to send rejection email: #{e.message}"
43
44
  end
@@ -0,0 +1,157 @@
1
+ module Dscf::Credit
2
+ class FacilitatorCreationService
3
+ attr_reader :current_user, :facilitator_class
4
+
5
+ def initialize(current_user, facilitator_class = Dscf::Credit::Facilitator)
6
+ @current_user = current_user
7
+ @facilitator_class = facilitator_class
8
+ end
9
+
10
+ # Creates a single facilitator
11
+ # @param facilitator_params [Hash] The facilitator parameters
12
+ # @return [Dscf::Credit::Facilitator] The created facilitator
13
+ # @raise [StandardError] If creation fails
14
+ def create_single(facilitator_params)
15
+ ActiveRecord::Base.transaction do
16
+ facilitator_data = build_facilitator_data(facilitator_params)
17
+ facilitator = facilitator_class.new(facilitator_data)
18
+ facilitator.kyc_reviewed_by = current_user
19
+ facilitator.kyc_review_date = Time.current
20
+
21
+ if facilitator.save
22
+ create_initial_performance(facilitator)
23
+ facilitator
24
+ else
25
+ raise StandardError, facilitator.errors.full_messages.join(", ")
26
+ end
27
+ end
28
+ end
29
+
30
+ # Creates multiple facilitators in batch
31
+ # @param facilitators_params [Array<Hash>] Array of facilitator parameters
32
+ # @return [Hash] Results containing successful and failed creations
33
+ def create_batch(facilitators_params)
34
+ validate_batch_params(facilitators_params)
35
+
36
+ results = initialize_batch_results(facilitators_params.length)
37
+
38
+ facilitators_params.each_with_index do |facilitator_attrs, index|
39
+ process_single_facilitator_in_batch(facilitator_attrs, index, results)
40
+ end
41
+
42
+ results
43
+ end
44
+
45
+ private
46
+
47
+ def build_facilitator_data(facilitator_params)
48
+ user = find_user(facilitator_params[:user_id])
49
+ business = find_user_business(user)
50
+
51
+ facilitator_params.to_h.merge(
52
+ name: business.name,
53
+ type: business.business_type.name.downcase
54
+ )
55
+ end
56
+
57
+ def find_user(user_id)
58
+ user = Dscf::Core::User.find(user_id)
59
+ raise StandardError, "User not found with ID: #{user_id}" unless user
60
+ user
61
+ rescue ActiveRecord::RecordNotFound
62
+ raise StandardError, "User not found with ID: #{user_id}"
63
+ end
64
+
65
+ def find_user_business(user)
66
+ business = user.businesses.first
67
+ raise StandardError, "User must have a business associated to become a facilitator" unless business
68
+ business
69
+ end
70
+
71
+ def create_initial_performance(facilitator)
72
+ facilitator.facilitator_performances.create!(
73
+ total_outstanding_loans: 0,
74
+ total_outstanding_amount: 0.0,
75
+ approval_required: false,
76
+ created_by: current_user
77
+ )
78
+ end
79
+
80
+ def validate_batch_params(facilitators_params)
81
+ unless facilitators_params.is_a?(Array)
82
+ raise StandardError, "Expected an array of facilitator objects"
83
+ end
84
+
85
+ if facilitators_params.empty?
86
+ raise StandardError, "At least one facilitator is required"
87
+ end
88
+
89
+ if facilitators_params.length > 100
90
+ raise StandardError, "Maximum 100 facilitators allowed per batch"
91
+ end
92
+ end
93
+
94
+ def initialize_batch_results(total_count)
95
+ {
96
+ successful: [],
97
+ failed: [],
98
+ total_count: total_count,
99
+ success_count: 0,
100
+ failure_count: 0
101
+ }
102
+ end
103
+
104
+ def process_single_facilitator_in_batch(facilitator_attrs, index, results)
105
+ begin
106
+ permitted_attrs = permit_facilitator_attrs(facilitator_attrs)
107
+ facilitator = create_single(permitted_attrs)
108
+
109
+ add_successful_result(results, index, facilitator)
110
+ rescue StandardError => e
111
+ add_failed_result(results, index, facilitator_attrs, e)
112
+ end
113
+ end
114
+
115
+ def permit_facilitator_attrs(facilitator_attrs)
116
+ if facilitator_attrs.is_a?(ActionController::Parameters)
117
+ facilitator_attrs.permit(:user_id, :bank_id, :kyc_status)
118
+ else
119
+ ActionController::Parameters.new(facilitator_attrs)
120
+ .permit(:user_id, :bank_id, :kyc_status)
121
+ end
122
+ end
123
+
124
+ def add_successful_result(results, index, facilitator)
125
+ results[:successful] << {
126
+ index: index,
127
+ id: facilitator.id,
128
+ name: facilitator.name,
129
+ message: "Successfully created"
130
+ }
131
+ results[:success_count] += 1
132
+ end
133
+
134
+ def add_failed_result(results, index, facilitator_attrs, error)
135
+ business_name = extract_business_name_for_error(facilitator_attrs)
136
+
137
+ results[:failed] << {
138
+ index: index,
139
+ name: business_name,
140
+ errors: [ error.message ]
141
+ }
142
+ results[:failure_count] += 1
143
+ end
144
+
145
+ def extract_business_name_for_error(facilitator_attrs)
146
+ user_id = facilitator_attrs.try(:[], :user_id) || facilitator_attrs[:user_id]
147
+ return "Unknown Business" unless user_id
148
+
149
+ begin
150
+ user = Dscf::Core::User.find(user_id)
151
+ user.businesses.first&.name || "No Business Associated"
152
+ rescue
153
+ "Invalid User ID"
154
+ end
155
+ end
156
+ end
157
+ end
@@ -41,18 +41,40 @@ en:
41
41
  update: "Failed to update bank staff"
42
42
  destroy: "Failed to remove bank staff"
43
43
 
44
+ scoring_param_type:
45
+ success:
46
+ index: "Scoring parameter types retrieved successfully"
47
+ show: "Scoring parameter type details retrieved successfully"
48
+ create: "Scoring parameter type created successfully"
49
+ update: "Scoring parameter type updated successfully"
50
+ destroy: "Scoring parameter type deleted successfully"
51
+ errors:
52
+ index: "Failed to retrieve scoring parameter types"
53
+ show: "Failed to retrieve scoring parameter type details"
54
+ create: "Failed to create scoring parameter type"
55
+ update: "Failed to update scoring parameter type"
56
+ destroy: "Failed to delete scoring parameter type"
57
+
44
58
  scoring_parameter:
45
59
  success:
46
60
  index: "Scoring parameters retrieved successfully"
47
61
  show: "Scoring parameter details retrieved successfully"
48
62
  create: "Scoring parameter created successfully"
49
63
  update: "Scoring parameter updated successfully"
64
+ approve: "Scoring parameter approved successfully"
65
+ reject: "Scoring parameter rejected successfully"
66
+ request_modification: "Modification requested for scoring parameter successfully"
67
+ resubmit: "Scoring parameter resubmitted successfully"
50
68
  destroy: "Scoring parameter deleted successfully"
51
69
  errors:
52
70
  index: "Failed to retrieve scoring parameters"
53
71
  show: "Failed to retrieve scoring parameter details"
54
72
  create: "Failed to create scoring parameter"
55
73
  update: "Failed to update scoring parameter"
74
+ approve: "Failed to approve scoring parameter"
75
+ reject: "Failed to reject scoring parameter"
76
+ request_modification: "Failed to request modification for scoring parameter"
77
+ resubmit: "Failed to resubmit scoring parameter"
56
78
  destroy: "Failed to delete scoring parameter"
57
79
 
58
80
  parameter_normalizer:
@@ -75,20 +97,24 @@ en:
75
97
  show: "Facilitator details retrieved successfully"
76
98
  create: "Facilitator created successfully"
77
99
  update: "Facilitator updated successfully"
78
- approved: "Facilitator approved successfully"
79
- rejected: "Facilitator rejected successfully"
80
- limit_updated: "Facilitator limit updated successfully"
81
- additional_info_submitted: "Additional information submitted successfully"
100
+ approve: "Facilitator approved successfully"
101
+ reject: "Facilitator rejected successfully"
102
+ set_limit: "Facilitator limit updated successfully"
103
+ submit_additional_info: "Additional information submitted successfully"
104
+ request_modification: "Modification requested for facilitator successfully"
105
+ resubmit: "Facilitator resubmitted successfully"
82
106
  batch_created_all: "All facilitators created successfully"
83
107
  batch_created_partial: "Batch processing completed with partial success"
84
108
  errors:
85
109
  create: "Failed to create facilitator"
86
110
  update: "Failed to update facilitator"
87
111
  show: "Failed to retrieve facilitator details"
88
- approval_failed: "Failed to approve facilitator"
89
- rejection_failed: "Failed to reject facilitator"
90
- limit_update_failed: "Failed to update facilitator limit"
91
- additional_info_failed: "Failed to submit additional information"
112
+ approve: "Failed to approve facilitator"
113
+ reject: "Failed to reject facilitator"
114
+ set_limit: "Failed to update facilitator limit"
115
+ submit_additional_info: "Failed to submit additional information"
116
+ request_modification: "Failed to request modification for facilitator"
117
+ resubmit: "Failed to resubmit facilitator"
92
118
  no_business: "User must have a business associated to become a facilitator"
93
119
  invalid_batch_format: "Invalid batch format"
94
120
  empty_batch: "Empty batch provided"
@@ -118,6 +144,8 @@ en:
118
144
  approve: "Credit line approved successfully"
119
145
  reject: "Credit line rejected successfully"
120
146
  destroy: "Credit line deleted successfully"
147
+ request_modification: "Modification requested successfully"
148
+ resubmit: "Credit line resubmitted successfully"
121
149
  errors:
122
150
  index: "Failed to retrieve credit lines"
123
151
  show: "Failed to retrieve credit line details"
@@ -126,6 +154,8 @@ en:
126
154
  approve: "Failed to approve credit line"
127
155
  reject: "Failed to reject credit line"
128
156
  destroy: "Failed to delete credit line"
157
+ request_modification: "Failed to request modification"
158
+ resubmit: "Failed to resubmit credit line"
129
159
 
130
160
  system_config_definition:
131
161
  success:
@@ -147,12 +177,20 @@ en:
147
177
  show: "System config details retrieved successfully"
148
178
  create: "System config created successfully"
149
179
  update: "System config updated successfully"
180
+ approve: "System config approved successfully"
181
+ reject: "System config rejected successfully"
182
+ request_modification: "Modification requested for system config successfully"
183
+ resubmit: "System config resubmitted successfully"
150
184
  destroy: "System config deleted successfully"
151
185
  errors:
152
186
  index: "Failed to retrieve system configs"
153
187
  show: "Failed to retrieve system config details"
154
188
  create: "Failed to create system config"
155
189
  update: "Failed to update system config"
190
+ approve: "Failed to approve system config"
191
+ reject: "Failed to reject system config"
192
+ request_modification: "Failed to request modification for system config"
193
+ resubmit: "Failed to resubmit system config"
156
194
  destroy: "Failed to delete system config"
157
195
 
158
196
  category:
data/config/routes.rb CHANGED
@@ -4,20 +4,21 @@ Dscf::Credit::Engine.routes.draw do
4
4
  resources :bank_branches
5
5
  resources :payments, only: [ :index, :show, :create, :update, :destroy ]
6
6
  resources :loans, only: [ :index, :show, :create, :update, :destroy ]
7
+ resources :scoring_param_types
7
8
 
8
9
  resources :facilitators, only: [ :index, :show, :create, :update, :destroy ] do
9
10
  collection do
10
11
  post "batch_create", to: "facilitators#batch_create"
12
+ post "additional_info", to: "facilitators#submit_additional_info"
11
13
  end
12
14
  member do
13
15
  patch "approve", to: "facilitators#approve"
14
16
  patch "reject", to: "facilitators#reject"
17
+ patch "request_modification", to: "facilitators#request_modification"
15
18
  patch "set_limit", to: "facilitators#set_limit"
16
19
  end
17
20
  end
18
21
 
19
- post "facilitators/additional_info", to: "facilitators#submit_additional_info"
20
-
21
22
  resources :loan_profiles, only: [ :index, :show, :create, :update, :destroy ] do
22
23
  member do
23
24
  get "kyc_review", to: "kyc_reviews#show"
@@ -26,14 +27,30 @@ Dscf::Credit::Engine.routes.draw do
26
27
  end
27
28
 
28
29
  resources :payment_requests
29
- resources :scoring_parameters
30
+ resources :scoring_parameters do
31
+ member do
32
+ patch "approve"
33
+ patch "reject"
34
+ patch "request_modification"
35
+ patch "resubmit"
36
+ end
37
+ end
30
38
  resources :parameter_normalizers
31
- resources :system_configs
39
+ resources :system_configs do
40
+ member do
41
+ patch "approve"
42
+ patch "reject"
43
+ patch "request_modification"
44
+ patch "resubmit"
45
+ end
46
+ end
32
47
  resources :system_config_definitions
33
48
  resources :credit_lines do
34
49
  member do
35
- patch "approve", to: "credit_lines#approve"
36
- patch "reject", to: "credit_lines#reject"
50
+ patch "approve"
51
+ patch "reject"
52
+ patch "request_modification"
53
+ patch "resubmit"
37
54
  end
38
55
  end
39
56
  resources :credit_line_specs
@@ -4,12 +4,14 @@ class CreateDscfCreditCategories < ActiveRecord::Migration[8.0]
4
4
  t.string :type, null: false
5
5
  t.string :name, null: false
6
6
  t.text :description
7
+ t.string :document_reference
7
8
 
8
9
  t.timestamps
9
10
  end
10
11
 
11
12
  add_index :dscf_credit_categories, :type
12
13
  add_index :dscf_credit_categories, :name
14
+ add_index :dscf_credit_categories, :document_reference
13
15
  add_index :dscf_credit_categories, [ :type, :name ], unique: true
14
16
  end
15
17
  end