dscf-credit 0.2.2 → 0.2.4

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: 3c8471bd555308d0b88c282f893299234859a46f02ae02c003f02b147115e1ae
4
- data.tar.gz: 3becd29b404c498ff195e300afa0c313a00155cb20d2ec600f39da1d36e1a45e
3
+ metadata.gz: '0883e69edbfba633fb3b886139de199303da27bfaa0ed9402c39d7ed036fb778'
4
+ data.tar.gz: e1ea1f2d623086de0e807c1e986cb340b41d10501056960a1f4c7f8b03b84192
5
5
  SHA512:
6
- metadata.gz: c205f203030be0f10872f4dcc1dac30b3ad797abe5a006a071bd579459bd13bf95fb821144d86f96c021e8eb1b7494e1544b6a046eb7b67150484cfeb7910116
7
- data.tar.gz: 4910b18be7d23f314940a74e70b2cf1e032b8134e50903ed1770283e5a363af87b5986f32d0308799620326fda211c123a735747d4d9eedd240c958153b87d66
6
+ metadata.gz: f624bce3e341b942f97bc54201f94f995db7dc8a507083c8061d6fdfc58e982f0f2c2f13b573c881b37ffc5e1170184db026c9ae247473a05aef86620620117f
7
+ data.tar.gz: ba02250152266b20ecca88cf929b2379b3931fd7d1f0dd9561d632e1928a6c15c7b83deaac2ffa8930601f8bd6de9969b7578a140a08d43aeb272070a95f5138
@@ -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
@@ -125,6 +145,24 @@ module Dscf::Credit
125
145
  end
126
146
  end
127
147
 
148
+ def create_loan_profile_for_approved_application(loan_application, score)
149
+ profile_service = LoanProfileCreationService.new(loan_application, score)
150
+ profile_result = profile_service.create_loan_profile
151
+
152
+ unless profile_result[:success]
153
+ error_message = "Failed to create loan profile for approved application #{loan_application.id}: #{profile_result[:error]}"
154
+ Rails.logger.error error_message
155
+ # Raise error to rollback the entire transaction including score and review status
156
+ raise StandardError, error_message
157
+ else
158
+ Rails.logger.info "Loan profile created successfully for approved application #{loan_application.id}"
159
+ end
160
+
161
+ profile_result
162
+ end
163
+
164
+
165
+
128
166
  private
129
167
 
130
168
  def update_review_status(loan_application, status)
@@ -171,20 +209,25 @@ module Dscf::Credit
171
209
  end
172
210
 
173
211
  # Create loan profile for approved applications
174
- def create_loan_profile_for_approved_application(loan_application, score)
212
+ def create_loan_profile_from_review(review)
213
+ loan_application = review.reviewable # Assumes Review belongs_to :reviewable (polymorphic or direct association to LoanApplication)
214
+ score = loan_application.score # Assumes score is already set on the loan application
215
+
216
+ unless score
217
+ Rails.logger.warn "No score available for loan application #{loan_application.id} during approve callback"
218
+ return
219
+ end
220
+
175
221
  profile_service = LoanProfileCreationService.new(loan_application, score)
176
222
  profile_result = profile_service.create_loan_profile
177
223
 
178
224
  unless profile_result[:success]
179
225
  error_message = "Failed to create loan profile for approved application #{loan_application.id}: #{profile_result[:error]}"
180
226
  Rails.logger.error error_message
181
- # Raise error to rollback the entire transaction including score and review status
182
- raise StandardError, error_message
227
+ raise StandardError, error_message # This will rollback the transaction in perform_review_action
183
228
  else
184
- Rails.logger.info "Loan profile created successfully for approved application #{loan_application.id}"
229
+ Rails.logger.info "Loan profile created successfully for approved application #{loan_application.id} via review callback"
185
230
  end
186
-
187
- profile_result
188
231
  end
189
232
 
190
233
  def model_params
@@ -255,7 +255,7 @@ module Dscf::Credit
255
255
  when 0...50
256
256
  "rejected"
257
257
  when 50..60
258
- "pending_review"
258
+ "pending"
259
259
  else # score > 60
260
260
  "approved"
261
261
  end
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."
@@ -1,5 +1,5 @@
1
1
  module Dscf
2
2
  module Credit
3
- VERSION = "0.2.2"
3
+ VERSION = "0.2.4"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dscf-credit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adoniyas