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.
- checksums.yaml +4 -4
- data/app/controllers/concerns/dscf/credit/reviewable.rb +112 -0
- data/app/controllers/dscf/credit/categories_controller.rb +3 -2
- data/app/controllers/dscf/credit/credit_lines_controller.rb +11 -38
- data/app/controllers/dscf/credit/facilitators_controller.rb +39 -150
- data/app/controllers/dscf/credit/scoring_param_types_controller.rb +31 -0
- data/app/controllers/dscf/credit/scoring_parameters_controller.rb +13 -8
- data/app/controllers/dscf/credit/system_configs_controller.rb +10 -7
- data/app/models/dscf/credit/category.rb +1 -1
- data/app/models/dscf/credit/credit_line.rb +7 -4
- data/app/models/dscf/credit/facilitator.rb +5 -4
- data/app/models/dscf/credit/facilitator_performance.rb +1 -2
- data/app/models/dscf/credit/loan_profile.rb +4 -3
- data/app/models/dscf/credit/loan_profile_scoring_spec.rb +3 -4
- data/app/models/dscf/credit/scoring_param_type.rb +17 -0
- data/app/models/dscf/credit/scoring_parameter.rb +7 -6
- data/app/models/dscf/credit/system_config.rb +5 -4
- data/app/serializers/dscf/credit/category_serializer.rb +1 -1
- data/app/serializers/dscf/credit/credit_line_serializer.rb +2 -2
- data/app/serializers/dscf/credit/facilitator_performance_serializer.rb +1 -1
- data/app/serializers/dscf/credit/facilitator_serializer.rb +2 -2
- data/app/serializers/dscf/credit/scoring_param_type_serializer.rb +7 -0
- data/app/serializers/dscf/credit/scoring_parameter_serializer.rb +4 -3
- data/app/serializers/dscf/credit/system_config_serializer.rb +2 -2
- data/app/services/dscf/credit/facilitator_approval_service.rb +4 -3
- data/app/services/dscf/credit/facilitator_creation_service.rb +157 -0
- data/config/locales/en.yml +46 -8
- data/config/routes.rb +23 -6
- data/db/migrate/20250822091011_create_dscf_credit_categories.rb +2 -0
- data/db/migrate/20250822091131_create_dscf_credit_credit_lines.rb +7 -4
- data/db/migrate/20250822091820_create_dscf_credit_system_configs.rb +5 -2
- data/db/migrate/20250822092040_create_dscf_credit_scoring_param_types.rb +12 -0
- data/db/migrate/20250822092050_create_dscf_credit_scoring_parameters.rb +11 -6
- data/db/migrate/20250822092246_create_dscf_credit_loan_profiles.rb +5 -3
- data/db/migrate/20250822092417_create_dscf_credit_loan_profile_scoring_specs.rb +5 -4
- data/db/migrate/20250822092436_create_dscf_credit_facilitators.rb +5 -2
- data/db/migrate/20250822092528_create_dscf_credit_facilitator_performances.rb +0 -3
- data/db/seeds.rb +48 -20
- data/lib/dscf/credit/version.rb +1 -1
- data/spec/factories/dscf/credit/categories.rb +1 -0
- data/spec/factories/dscf/credit/credit_lines.rb +7 -5
- data/spec/factories/dscf/credit/facilitator_performances.rb +0 -5
- data/spec/factories/dscf/credit/facilitators.rb +6 -1
- data/spec/factories/dscf/credit/loan_profile_scoring_specs.rb +3 -6
- data/spec/factories/dscf/credit/loan_profiles.rb +10 -6
- data/spec/factories/dscf/credit/scoring_param_types.rb +31 -0
- data/spec/factories/dscf/credit/scoring_parameters.rb +26 -4
- data/spec/factories/dscf/credit/system_configs.rb +8 -2
- 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 :
|
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
|
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 :
|
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 :
|
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
|
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
|
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 :
|
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
|
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
|
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 :
|
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, :
|
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
|
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
|
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 :
|
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
|
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, :
|
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 :
|
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
|
-
:
|
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 :
|
8
|
+
belongs_to :kyc_reviewed_by, polymorphic: true
|
9
9
|
has_many :facilitator_performances, serializer: Dscf::Credit::FacilitatorPerformanceSerializer
|
10
10
|
end
|
11
11
|
end
|
@@ -1,11 +1,12 @@
|
|
1
1
|
module Dscf::Credit
|
2
2
|
class ScoringParameterSerializer < ActiveModel::Serializer
|
3
|
-
attributes :id, :name, :description, :data_type, :
|
4
|
-
:max_value, :active, :
|
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 :
|
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 :
|
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(
|
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,
|
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
|
data/config/locales/en.yml
CHANGED
@@ -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
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
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
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
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"
|
36
|
-
patch "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
|