dscf-credit 0.2.2 → 0.2.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.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c03116320f239a1f9f953742c429298bf629e0731e1938dc1870107bd2e3a74f
|
4
|
+
data.tar.gz: da5c7c4a877ce2c82cd0300c25c9686f8ea1254bcfd9b82c856ecd99fb8ef5a7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0ae96ca00a9c2cef5bb46b59a58e0b4cf13263cb89903a19bbf8c1a03c709d2a75ac59e4ea394668c4a5f2b2ea298cbfd963c22eb1af810a5fb4c6ed9c266bb3
|
7
|
+
data.tar.gz: 879a870adbb92ac789ed00096d658e1c729107b94572c4ee66df10c31fcf123b549ceec50499b295cb16e94f446f0218ad7f0c6430fd5839c9c91f31e4ff19fb
|
@@ -2,6 +2,26 @@ module Dscf::Credit
|
|
2
2
|
class LoanApplicationsController < ApplicationController
|
3
3
|
include Dscf::Core::Common
|
4
4
|
include Dscf::Core::ReviewableController
|
5
|
+
reviewable_context :default,
|
6
|
+
statuses: %w[pending approved rejected modify],
|
7
|
+
initial_status: "pending",
|
8
|
+
transitions: {
|
9
|
+
"pending" => %w[approved rejected modify],
|
10
|
+
"modify" => [ "pending" ]
|
11
|
+
},
|
12
|
+
actions: {
|
13
|
+
approve: {
|
14
|
+
status: "approved",
|
15
|
+
after: ->(review) {
|
16
|
+
loan_application = review.reviewable
|
17
|
+
score = loan_application.score
|
18
|
+
LoanApplicationsController.new.create_loan_profile_for_approved_application(loan_application, score)
|
19
|
+
}
|
20
|
+
},
|
21
|
+
reject: { status: "rejected", require_feedback: true },
|
22
|
+
request_modification: { status: "modify", require_feedback: true },
|
23
|
+
resubmit: { status: "pending", update_model: true }
|
24
|
+
}
|
5
25
|
|
6
26
|
def create
|
7
27
|
super do
|
@@ -187,6 +207,27 @@ module Dscf::Credit
|
|
187
207
|
profile_result
|
188
208
|
end
|
189
209
|
|
210
|
+
def create_loan_profile_from_review(review)
|
211
|
+
loan_application = review.reviewable # Assumes Review belongs_to :reviewable (polymorphic or direct association to LoanApplication)
|
212
|
+
score = loan_application.score # Assumes score is already set on the loan application
|
213
|
+
|
214
|
+
unless score
|
215
|
+
Rails.logger.warn "No score available for loan application #{loan_application.id} during approve callback"
|
216
|
+
return
|
217
|
+
end
|
218
|
+
|
219
|
+
profile_service = LoanProfileCreationService.new(loan_application, score)
|
220
|
+
profile_result = profile_service.create_loan_profile
|
221
|
+
|
222
|
+
unless profile_result[:success]
|
223
|
+
error_message = "Failed to create loan profile for approved application #{loan_application.id}: #{profile_result[:error]}"
|
224
|
+
Rails.logger.error error_message
|
225
|
+
raise StandardError, error_message # This will rollback the transaction in perform_review_action
|
226
|
+
else
|
227
|
+
Rails.logger.info "Loan profile created successfully for approved application #{loan_application.id} via review callback"
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
190
231
|
def model_params
|
191
232
|
params.require(:loan_application).permit(
|
192
233
|
:bank_id,
|
data/db/seeds.rb
CHANGED
@@ -568,99 +568,6 @@ puts "Seeding loan profile scoring specs..."
|
|
568
568
|
# Note: This will be moved after loan profiles are created
|
569
569
|
|
570
570
|
# 10.5. Loan Applications (depends on banks, users, and bank branches)
|
571
|
-
puts "Seeding loan applications..."
|
572
|
-
loan_application1 = Dscf::Credit::LoanApplication.find_or_create_by(
|
573
|
-
bank: bunna_bank,
|
574
|
-
user_id: user2.id,
|
575
|
-
review_branch: bunna_head_office
|
576
|
-
) do |application|
|
577
|
-
application.backer = user1
|
578
|
-
application.bank_statement_source = "internal"
|
579
|
-
application.user_info = {
|
580
|
-
name: "Jane Smith",
|
581
|
-
phone: "+251922334455",
|
582
|
-
email: "jane.smith@example.com",
|
583
|
-
address: "123 Main St, Addis Ababa",
|
584
|
-
id_number: "ID123456789",
|
585
|
-
date_of_birth: "1985-05-15"
|
586
|
-
}
|
587
|
-
application.facilitator_info = {
|
588
|
-
business_name: "ABC Trading Company",
|
589
|
-
license_number: "LIC001234",
|
590
|
-
business_type: "retail",
|
591
|
-
years_in_business: 5,
|
592
|
-
monthly_turnover: 150000.00
|
593
|
-
}
|
594
|
-
application.bank_info = {
|
595
|
-
account_number: "123456789012",
|
596
|
-
account_holder: "Jane Smith",
|
597
|
-
bank_name: "Bunna Bank",
|
598
|
-
branch_name: "Head Office"
|
599
|
-
}
|
600
|
-
application.field_assessment = {
|
601
|
-
credit_score: 720,
|
602
|
-
risk_level: "medium",
|
603
|
-
recommendation: "approved",
|
604
|
-
assessed_by: "Field Officer A",
|
605
|
-
assessment_date: Time.current.iso8601
|
606
|
-
}
|
607
|
-
end
|
608
|
-
|
609
|
-
# Create approved review for loan_application1
|
610
|
-
Dscf::Core::Review.find_or_create_by(
|
611
|
-
reviewable: loan_application1,
|
612
|
-
reviewed_by: admin_user
|
613
|
-
) do |review|
|
614
|
-
review.status = 'approved'
|
615
|
-
review.reviewed_at = Time.current
|
616
|
-
end
|
617
|
-
|
618
|
-
loan_application2 = Dscf::Credit::LoanApplication.find_or_create_by(
|
619
|
-
bank: bunna_bank,
|
620
|
-
user_id: user3.id,
|
621
|
-
review_branch: bunna_merkato_branch
|
622
|
-
) do |application|
|
623
|
-
application.backer = user1
|
624
|
-
application.bank_statement_source = "external"
|
625
|
-
application.user_info = {
|
626
|
-
name: "Mike Johnson",
|
627
|
-
phone: "+251933445566",
|
628
|
-
email: "mike.johnson@example.com",
|
629
|
-
address: "456 Oak Ave, Addis Ababa",
|
630
|
-
id_number: "ID987654321",
|
631
|
-
date_of_birth: "1980-12-10"
|
632
|
-
}
|
633
|
-
application.facilitator_info = {
|
634
|
-
business_name: "XYZ Wholesale",
|
635
|
-
license_number: "LIC005678",
|
636
|
-
business_type: "wholesale",
|
637
|
-
years_in_business: 8,
|
638
|
-
monthly_turnover: 500000.00
|
639
|
-
}
|
640
|
-
application.bank_info = {
|
641
|
-
account_number: "987654321098",
|
642
|
-
account_holder: "Mike Johnson",
|
643
|
-
bank_name: "Commercial Bank",
|
644
|
-
branch_name: "Main Branch"
|
645
|
-
}
|
646
|
-
application.field_assessment = {
|
647
|
-
credit_score: 650,
|
648
|
-
risk_level: "high",
|
649
|
-
recommendation: "conditional_approval",
|
650
|
-
assessed_by: "Field Officer B",
|
651
|
-
assessment_date: Time.current.iso8601
|
652
|
-
}
|
653
|
-
application.score = 65.0
|
654
|
-
end
|
655
|
-
|
656
|
-
# Create pending review for loan_application2
|
657
|
-
Dscf::Core::Review.find_or_create_by(
|
658
|
-
reviewable: loan_application2,
|
659
|
-
reviewed_by: bank_admin
|
660
|
-
) do |review|
|
661
|
-
review.status = 'pending'
|
662
|
-
review.reviewed_at = Time.current
|
663
|
-
end
|
664
571
|
|
665
572
|
# 10.6. Facilitator Applications (depends on users and banks)
|
666
573
|
puts "Seeding facilitator applications..."
|
@@ -750,119 +657,6 @@ Dscf::Core::Review.find_or_create_by(
|
|
750
657
|
end
|
751
658
|
|
752
659
|
# 11. Loan Profiles (depends on loan applications)
|
753
|
-
puts "Seeding loan profiles..."
|
754
|
-
loan_profile1 = Dscf::Credit::LoanProfile.find_or_create_by(
|
755
|
-
loan_application: loan_application1
|
756
|
-
) do |profile|
|
757
|
-
profile.code = "BB000001"
|
758
|
-
profile.score = 78.5
|
759
|
-
profile.total_limit = 100000.00
|
760
|
-
end
|
761
|
-
|
762
|
-
# Create approved review for loan_profile1
|
763
|
-
Dscf::Core::Review.find_or_create_by(
|
764
|
-
reviewable: loan_profile1,
|
765
|
-
reviewed_by: admin_user
|
766
|
-
) do |review|
|
767
|
-
review.status = 'approved'
|
768
|
-
review.reviewed_at = Time.current
|
769
|
-
end
|
770
|
-
|
771
|
-
# 12. Loan Profile Scoring Specs (depends on loan profiles)
|
772
|
-
puts "Seeding loan profile scoring specs..."
|
773
|
-
Dscf::Credit::LoanProfileScoringSpec.create!(
|
774
|
-
loan_profile: loan_profile1,
|
775
|
-
scoring_input_data: {
|
776
|
-
'monthly_income' => 45000,
|
777
|
-
'credit_history_score' => 720,
|
778
|
-
'employment_type' => 'permanent',
|
779
|
-
'years_at_job' => 3,
|
780
|
-
'existing_debt' => 15000,
|
781
|
-
'average_daily_purchase' => 15000 # Wholesaler's average daily purchase volume
|
782
|
-
},
|
783
|
-
score: 78.5,
|
784
|
-
total_limit: 100000.00,
|
785
|
-
active: true,
|
786
|
-
created_by: admin_user
|
787
|
-
)
|
788
|
-
|
789
|
-
# 11. Eligible Credit Lines (depends on loan profiles and credit lines)
|
790
|
-
puts "Seeding eligible credit lines..."
|
791
|
-
Dscf::Credit::EligibleCreditLine.create!(
|
792
|
-
loan_profile: loan_profile1,
|
793
|
-
credit_line: credit_line1,
|
794
|
-
credit_limit: 75000.00,
|
795
|
-
available_limit: 67500.00,
|
796
|
-
risk: 0.35
|
797
|
-
)
|
798
|
-
|
799
|
-
Dscf::Credit::EligibleCreditLine.create!(
|
800
|
-
loan_profile: loan_profile1,
|
801
|
-
credit_line: credit_line2,
|
802
|
-
credit_limit: 50000.00,
|
803
|
-
available_limit: 42500.00,
|
804
|
-
risk: 0.45
|
805
|
-
)
|
806
|
-
|
807
|
-
# 12. Loans (depends on loan profiles and credit lines)
|
808
|
-
puts "Seeding loans..."
|
809
|
-
loan1 = Dscf::Credit::Loan.create!(
|
810
|
-
loan_profile: loan_profile1,
|
811
|
-
credit_line: credit_line1,
|
812
|
-
status: 'active',
|
813
|
-
principal_amount: 50000.00,
|
814
|
-
remaining_amount: 50000.00,
|
815
|
-
due_date: 3.months.from_now.to_date,
|
816
|
-
disbursed_at: 1.day.ago,
|
817
|
-
active: true
|
818
|
-
)
|
819
|
-
|
820
|
-
# 12.5. Loan Accruals (depends on loans)
|
821
|
-
puts "Seeding loan accruals..."
|
822
|
-
Dscf::Credit::LoanAccrual.create!(
|
823
|
-
loan: loan1,
|
824
|
-
accrual_type: 'interest',
|
825
|
-
amount: 250.00,
|
826
|
-
applied_on: 1.month.ago.to_date,
|
827
|
-
status: 'pending'
|
828
|
-
)
|
829
|
-
|
830
|
-
Dscf::Credit::LoanAccrual.create!(
|
831
|
-
loan: loan1,
|
832
|
-
accrual_type: 'facilitation_fee',
|
833
|
-
amount: 1000.00,
|
834
|
-
applied_on: 1.day.ago.to_date,
|
835
|
-
status: 'paid'
|
836
|
-
)
|
837
|
-
|
838
|
-
# 13. Loan Transactions (depends on loans)
|
839
|
-
puts "Seeding loan transactions..."
|
840
|
-
Dscf::Credit::LoanTransaction.create!(
|
841
|
-
loan: loan1,
|
842
|
-
transaction_type: 'disbursement',
|
843
|
-
amount: 50000.00,
|
844
|
-
transaction_reference: "TXN-DISB-#{Time.current.to_i}",
|
845
|
-
status: 'completed'
|
846
|
-
)
|
847
|
-
|
848
|
-
Dscf::Credit::LoanTransaction.create!(
|
849
|
-
loan: loan1,
|
850
|
-
transaction_type: 'interest_accrual',
|
851
|
-
amount: 2500.00,
|
852
|
-
transaction_reference: "TXN-INT-#{Time.current.to_i}",
|
853
|
-
status: 'completed'
|
854
|
-
)
|
855
|
-
|
856
|
-
# 14. Daily Routine Transactions (depends on loans)
|
857
|
-
puts "Seeding daily routine transactions..."
|
858
|
-
Dscf::Credit::DailyRoutineTransaction.create!(
|
859
|
-
loan: loan1,
|
860
|
-
routine_type: 'interest_calculation',
|
861
|
-
amount: 83.33,
|
862
|
-
status: 'completed',
|
863
|
-
initiated_at: Date.current.beginning_of_day,
|
864
|
-
approved_at: Date.current.beginning_of_day + 1.hour
|
865
|
-
)
|
866
660
|
|
867
661
|
puts "DSCF Credit Engine seed data completed successfully!"
|
868
662
|
puts "Created sample data for all models with proper relationships."
|
data/lib/dscf/credit/version.rb
CHANGED