dscf-banking 0.1.0 → 0.1.1

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: 3bc685fe54cfe3ac3a4eaa5f241c70e71fabbb659daed56ff93ba9d40762c262
4
- data.tar.gz: 7ba510d6818243bded3582c1ddaa66e87a92f3ebcf7bf7a1f393d83064ff811c
3
+ metadata.gz: e27d20f9d483fe4d6cad89eee3cfca5b645b7f0506533417239094a374f2d605
4
+ data.tar.gz: 35544741b37e86abbba9b2fe5340385e2ba5548a707af606f590b9cde3427666
5
5
  SHA512:
6
- metadata.gz: 4ddabc45b7019977470f880cb364e853ba7269319ecede9d7d2f75db6c6e99fed19ca6bc915e7f613b6367d5abe0360850e2aeaf84312db58c8197091a6114ed
7
- data.tar.gz: 7e038bfe9f2a4558e05971d4cc11374e779553fd72a953d7db25a743c7f334ed6ea758126aeaa30a9f8c63684be617178ab0f6d64eb57560f01c4ad7fbd48730
6
+ metadata.gz: 5d4dc562bceac06f973435d2b9ea61983a426374b498a184df51da088cff5a6cf8bc4cae0cd7a339beb201dda12285ff74f821c7ef961f02cf9df88974d0c3ee
7
+ data.tar.gz: 698c1120914bc32176231f198b6538b6d5a18338b3fd14ed5d1461d5a36b6ed61fbb5cd25064b82426ce77684691a0ac4b5ce9df14643424d8939bd2a77a79d5
@@ -0,0 +1,152 @@
1
+ module Dscf::Banking
2
+ class AccountsController < ApplicationController
3
+ include Dscf::Core::Common
4
+
5
+ def activate
6
+ account = Dscf::Banking::Account.find(params[:id])
7
+
8
+ unless account.can_be_activated?
9
+ return render json: {
10
+ success: false,
11
+ error: "Failed to activate account",
12
+ errors: [ "Account cannot be activated from current status: #{account.status}" ]
13
+ }, status: :unprocessable_entity
14
+ end
15
+
16
+ if account.activate!
17
+ render json: {
18
+ success: true,
19
+ data: account_data(account),
20
+ message: "Account activated successfully"
21
+ }
22
+ else
23
+ render json: {
24
+ success: false,
25
+ error: "Failed to activate account",
26
+ errors: account.errors.full_messages
27
+ }, status: :unprocessable_entity
28
+ end
29
+ rescue ActiveRecord::RecordNotFound
30
+ render json: {
31
+ success: false,
32
+ error: "Account not found"
33
+ }, status: :not_found
34
+ end
35
+
36
+ def suspend
37
+ account = Dscf::Banking::Account.find(params[:id])
38
+
39
+ unless account.can_be_suspended?
40
+ return render json: {
41
+ success: false,
42
+ error: "Failed to suspend account",
43
+ errors: [ "Account cannot be suspended from current status: #{account.status}" ]
44
+ }, status: :unprocessable_entity
45
+ end
46
+
47
+ if account.suspend!
48
+ render json: {
49
+ success: true,
50
+ data: account_data(account),
51
+ message: "Account suspended successfully"
52
+ }
53
+ else
54
+ render json: {
55
+ success: false,
56
+ error: "Failed to suspend account",
57
+ errors: account.errors.full_messages
58
+ }, status: :unprocessable_entity
59
+ end
60
+ rescue ActiveRecord::RecordNotFound
61
+ render json: {
62
+ success: false,
63
+ error: "Account not found"
64
+ }, status: :not_found
65
+ end
66
+
67
+ def close
68
+ account = Dscf::Banking::Account.find(params[:id])
69
+
70
+ unless account.can_be_closed?
71
+ return render json: {
72
+ success: false,
73
+ error: "Failed to close account",
74
+ errors: [ "Account cannot be closed from current status: #{account.status}" ]
75
+ }, status: :unprocessable_entity
76
+ end
77
+
78
+ if account.close!
79
+ render json: {
80
+ success: true,
81
+ data: account_data(account),
82
+ message: "Account closed successfully"
83
+ }
84
+ else
85
+ render json: {
86
+ success: false,
87
+ error: "Failed to close account",
88
+ errors: account.errors.full_messages
89
+ }, status: :unprocessable_entity
90
+ end
91
+ rescue ActiveRecord::RecordNotFound
92
+ render json: {
93
+ success: false,
94
+ error: "Account not found"
95
+ }, status: :not_found
96
+ end
97
+
98
+ private
99
+
100
+ def account_data(account)
101
+ {
102
+ id: account.id,
103
+ account_number: account.account_number,
104
+ name: account.name,
105
+ status: account.status,
106
+ activation_date: account.activation_date,
107
+ closure_date: account.closure_date,
108
+ current_balance: account.current_balance,
109
+ available_balance: account.available_balance,
110
+ minimum_balance: account.minimum_balance,
111
+ currency: account.currency,
112
+ active: account.active,
113
+ application_id: account.application_id,
114
+ virtual_account_product_id: account.virtual_account_product_id,
115
+ created_at: account.created_at,
116
+ updated_at: account.updated_at
117
+ }
118
+ end
119
+
120
+ def model_params
121
+ params.require(:payload).permit(
122
+ :application_id,
123
+ :virtual_account_product_id,
124
+ :name,
125
+ :status,
126
+ :activation_date,
127
+ :closure_date,
128
+ :current_balance,
129
+ :available_balance,
130
+ :minimum_balance,
131
+ :currency,
132
+ :active,
133
+ account_properties: {}
134
+ )
135
+ end
136
+
137
+ def eager_loaded_associations
138
+ [ :application, :virtual_account_product ]
139
+ end
140
+
141
+ def allowed_order_columns
142
+ %w[id account_number name status activation_date closure_date current_balance created_at updated_at]
143
+ end
144
+
145
+ def default_serializer_includes
146
+ {
147
+ application: {},
148
+ virtual_account_product: {}
149
+ }
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,113 @@
1
+ module Dscf::Banking
2
+ class ApplicationsController < ApplicationController
3
+ include Dscf::Core::Common
4
+
5
+ def approve
6
+ application = Dscf::Banking::Application.find(params[:id])
7
+
8
+ unless application.can_be_approved_via_api?
9
+ return render json: {
10
+ success: false,
11
+ error: "Failed to approve application",
12
+ errors: [ "Application cannot be approved from current status: #{application.status}" ]
13
+ }, status: :unprocessable_entity
14
+ end
15
+
16
+ if application.approve!
17
+ render json: {
18
+ success: true,
19
+ data: application_data(application),
20
+ message: "Application approved successfully"
21
+ }
22
+ else
23
+ render json: {
24
+ success: false,
25
+ error: "Failed to approve application",
26
+ errors: application.errors.full_messages
27
+ }, status: :unprocessable_entity
28
+ end
29
+ rescue ActiveRecord::RecordNotFound
30
+ render json: {
31
+ success: false,
32
+ error: "Application not found"
33
+ }, status: :not_found
34
+ end
35
+
36
+ def reject
37
+ application = Dscf::Banking::Application.find(params[:id])
38
+ rejection_reason = params[:rejection_reason]
39
+
40
+ unless application.can_be_rejected_via_api?
41
+ return render json: {
42
+ success: false,
43
+ error: "Failed to reject application",
44
+ errors: [ "Application cannot be rejected from current status: #{application.status}" ]
45
+ }, status: :unprocessable_entity
46
+ end
47
+
48
+ if application.reject!(rejection_reason)
49
+ render json: {
50
+ success: true,
51
+ data: application_data(application),
52
+ message: "Application rejected successfully"
53
+ }
54
+ else
55
+ render json: {
56
+ success: false,
57
+ error: "Failed to reject application",
58
+ errors: application.errors.full_messages
59
+ }, status: :unprocessable_entity
60
+ end
61
+ rescue ActiveRecord::RecordNotFound
62
+ render json: {
63
+ success: false,
64
+ error: "Application not found"
65
+ }, status: :not_found
66
+ end
67
+
68
+ private
69
+
70
+ def application_data(application)
71
+ {
72
+ id: application.id,
73
+ application_number: application.application_number,
74
+ applicant_type: application.applicant_type,
75
+ status: application.status,
76
+ user_id: application.user_id,
77
+ virtual_account_product_id: application.virtual_account_product_id,
78
+ form_data: application.form_data,
79
+ submitted_at: application.submitted_at,
80
+ completed_at: application.completed_at,
81
+ rejection_reason: application.rejection_reason,
82
+ created_at: application.created_at,
83
+ updated_at: application.updated_at
84
+ }
85
+ end
86
+
87
+ def model_params
88
+ params.require(:payload).permit(
89
+ :user_id,
90
+ :virtual_account_product_id,
91
+ :applicant_type,
92
+ :status,
93
+ form_data: {}
94
+ )
95
+ end
96
+
97
+ def eager_loaded_associations
98
+ [ :user, :virtual_account_product ]
99
+ end
100
+
101
+ def allowed_order_columns
102
+ %w[id application_number status submitted_at completed_at created_at updated_at]
103
+ end
104
+
105
+ def default_serializer_includes
106
+ {
107
+ user: {},
108
+ virtual_account_product: {},
109
+ account: {}
110
+ }
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,88 @@
1
+ module Dscf::Banking
2
+ class Account < ApplicationRecord
3
+ belongs_to :virtual_account_product
4
+ belongs_to :application
5
+
6
+ enum :status, {
7
+ draft: 0,
8
+ pending_activation: 1,
9
+ active: 2,
10
+ suspended: 3,
11
+ closed: 4,
12
+ dormant: 5
13
+ }
14
+
15
+ validates :account_number, presence: true, uniqueness: { case_sensitive: false }
16
+ validates :name, presence: true
17
+ validates :currency, presence: true
18
+ validates :current_balance, :available_balance, :minimum_balance,
19
+ numericality: { greater_than_or_equal_to: 0 }
20
+
21
+ before_validation :generate_account_number, on: :create
22
+ before_validation :set_defaults, on: :create
23
+
24
+ scope :active_accounts, -> { where(active: true, status: :active) }
25
+ scope :by_currency, ->(currency) { where(currency: currency) }
26
+
27
+ def sufficient_funds_for_withdrawal?(amount)
28
+ available_balance - amount >= minimum_balance
29
+ end
30
+
31
+ def suspend!(reason = nil)
32
+ update!(status: :suspended)
33
+ end
34
+
35
+ def activate!
36
+ update!(status: :active, activation_date: Date.current)
37
+ end
38
+
39
+ def close!(reason = nil)
40
+ update!(status: :closed, active: false, closure_date: Date.current)
41
+ end
42
+
43
+ def formatted_account_number
44
+ return nil unless account_number
45
+ account_number.gsub(/(\d{3})(\d{1})(\d{1})(\d{6})/, '\1 \2 \3 \4')
46
+ end
47
+
48
+ def can_be_activated?
49
+ draft? || pending_activation? || suspended?
50
+ end
51
+
52
+ def can_be_suspended?
53
+ active?
54
+ end
55
+
56
+ def can_be_closed?
57
+ active? || suspended? || dormant?
58
+ end
59
+
60
+ private
61
+
62
+ def generate_account_number
63
+ return if account_number.present?
64
+
65
+ branch_code = "001"
66
+ product_scheme = "1"
67
+ voucher_type = "0"
68
+
69
+ loop do
70
+ sequence = SecureRandom.random_number(1000000).to_s.rjust(6, "0")
71
+ account_num = "#{branch_code}#{product_scheme}#{voucher_type}#{sequence}"
72
+
73
+ unless self.class.exists?(account_number: account_num)
74
+ self.account_number = account_num
75
+ break
76
+ end
77
+ end
78
+ end
79
+
80
+ def set_defaults
81
+ return unless virtual_account_product
82
+
83
+ self.currency ||= "ETB"
84
+ self.minimum_balance ||= 0
85
+ self.name ||= "Account Holder"
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,70 @@
1
+ module Dscf::Banking
2
+ class Application < ApplicationRecord
3
+ include Dscf::Banking::Auditable
4
+
5
+ belongs_to :user, class_name: "Dscf::Core::User"
6
+ belongs_to :assigned_kyc_officer, class_name: "Dscf::Core::User", optional: true
7
+ belongs_to :assigned_branch_manager, class_name: "Dscf::Core::User", optional: true
8
+ belongs_to :virtual_account_product, class_name: "Dscf::Banking::VirtualAccountProduct"
9
+ has_one :account, class_name: "Dscf::Banking::Account"
10
+
11
+ validates :application_number, presence: true, uniqueness: true, length: { maximum: 50 }
12
+ validates :applicant_type, presence: true
13
+ validates :status, presence: true
14
+ validates :form_data, presence: true
15
+ validates :rejection_reason, presence: true, if: -> { status == "rejected" }
16
+
17
+ enum :applicant_type, { individual: 0, business: 1 }, prefix: :applicant_type
18
+ enum :status, { draft: 0, submitted: 1, under_review: 2, approved: 3, rejected: 4 }, prefix: :status
19
+
20
+ before_validation :generate_application_number, if: -> { new_record? && application_number.blank? }
21
+ before_update :set_timestamps_on_status_change
22
+ after_update :create_account_if_approved
23
+
24
+ def approve!(approved_by = nil)
25
+ update!(status: :approved, completed_at: Time.current)
26
+ end
27
+
28
+ def reject!(reason, rejected_by = nil)
29
+ update!(status: :rejected, rejection_reason: reason, completed_at: Time.current)
30
+ end
31
+
32
+ def can_be_approved_via_api?
33
+ status_submitted? || status_under_review?
34
+ end
35
+
36
+ def can_be_rejected_via_api?
37
+ status_submitted? || status_under_review?
38
+ end
39
+
40
+ def has_account?
41
+ Account.exists?(application: self)
42
+ end
43
+
44
+ def create_account_if_approved
45
+ if saved_change_to_status? && status_approved?
46
+ AccountCreationService.call(self)
47
+ end
48
+ end
49
+
50
+ private
51
+
52
+ def generate_application_number
53
+ prefix = applicant_type == "individual" ? "IND" : "BUS"
54
+ timestamp = Time.current.strftime("%Y%m%d")
55
+ random_suffix = SecureRandom.random_number(10000).to_s.rjust(4, "0")
56
+ self.application_number = "#{prefix}#{timestamp}#{random_suffix}"
57
+ end
58
+
59
+ def set_timestamps_on_status_change
60
+ if status_changed?
61
+ case status
62
+ when "submitted"
63
+ self.submitted_at = Time.current
64
+ when "completed"
65
+ self.completed_at = Time.current
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,11 @@
1
+ module Dscf::Banking
2
+ class AccountSerializer < ActiveModel::Serializer
3
+ attributes :id, :account_number, :name, :status, :activation_date, :closure_date,
4
+ :account_properties, :current_balance, :available_balance, :minimum_balance,
5
+ :currency, :active, :created_at, :updated_at
6
+
7
+ belongs_to :virtual_account_product, serializer: VirtualAccountProductSerializer
8
+
9
+ attribute :application_id
10
+ end
11
+ end
@@ -0,0 +1,16 @@
1
+ module Dscf::Banking
2
+ class ApplicationSerializer < ActiveModel::Serializer
3
+ attributes :id, :application_number, :applicant_type, :status, :form_data,
4
+ :submitted_at, :completed_at, :rejection_reason, :created_at, :updated_at
5
+
6
+ belongs_to :user
7
+ belongs_to :virtual_account_product, serializer: VirtualAccountProductSerializer
8
+ belongs_to :assigned_kyc_officer, optional: true
9
+ belongs_to :assigned_branch_manager, optional: true
10
+ has_one :account, serializer: AccountSerializer, if: :has_account?
11
+
12
+ def has_account?
13
+ object.has_account?
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,53 @@
1
+ module Dscf::Banking
2
+ class AccountCreationService
3
+ def self.call(application)
4
+ new(application).call
5
+ end
6
+
7
+ def initialize(application)
8
+ @application = application
9
+ end
10
+
11
+ def call
12
+ return nil unless @application.status_approved?
13
+ return nil if account_already_exists?
14
+
15
+ create_account
16
+ rescue => e
17
+ Rails.logger.error "Account creation failed: #{e.message}" if defined?(Rails)
18
+ nil
19
+ end
20
+
21
+ private
22
+
23
+ attr_reader :application
24
+
25
+ def account_already_exists?
26
+ Account.exists?(application: @application)
27
+ end
28
+
29
+ def create_account
30
+ account = Account.new(
31
+ application: @application,
32
+ virtual_account_product: @application.virtual_account_product,
33
+ name: generate_account_name,
34
+ currency: "ETB",
35
+ minimum_balance: 0,
36
+ current_balance: 0,
37
+ available_balance: 0,
38
+ status: :draft
39
+ )
40
+
41
+ if account.save
42
+ account
43
+ else
44
+ Rails.logger.error "Account validation failed: #{account.errors.full_messages}" if defined?(Rails)
45
+ nil
46
+ end
47
+ end
48
+
49
+ def generate_account_name
50
+ "Test Account - #{@application.application_number}"
51
+ end
52
+ end
53
+ end
data/config/routes.rb CHANGED
@@ -1,4 +1,11 @@
1
1
  Dscf::Banking::Engine.routes.draw do
2
+ resources :accounts do
3
+ member do
4
+ post :activate
5
+ post :suspend
6
+ post :close
7
+ end
8
+ end
2
9
  resources :product_categories
3
10
  resources :interest_rate_types
4
11
  resources :virtual_account_products do
@@ -9,4 +16,10 @@ Dscf::Banking::Engine.routes.draw do
9
16
  resources :interest_configurations
10
17
  resources :interest_rate_tiers
11
18
  resources :product_approvals
19
+ resources :applications do
20
+ member do
21
+ post :approve
22
+ post :reject
23
+ end
24
+ end
12
25
  end
@@ -0,0 +1,20 @@
1
+ class CreateDscfBankingApplications < ActiveRecord::Migration[8.0]
2
+ def change
3
+ create_table :dscf_banking_applications do |t|
4
+ t.string :application_number, null: false
5
+ t.references :user, null: false, foreign_key: { to_table: :dscf_core_users }
6
+ t.integer :applicant_type, null: false
7
+ t.integer :status, null: false, default: 0
8
+
9
+ t.jsonb :form_data
10
+ t.datetime :submitted_at
11
+ t.datetime :completed_at
12
+ t.text :rejection_reason
13
+ t.references :assigned_kyc_officer, null: true, foreign_key: { to_table: :dscf_core_users }
14
+ t.references :assigned_branch_manager, null: true, foreign_key: { to_table: :dscf_core_users }
15
+ t.references :virtual_account_product, null: false, foreign_key: { to_table: :dscf_banking_virtual_account_products }
16
+
17
+ t.timestamps
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,21 @@
1
+ class CreateDscfBankingAccounts < ActiveRecord::Migration[8.0]
2
+ def change
3
+ create_table :dscf_banking_accounts do |t|
4
+ t.string :account_number, null: false
5
+ t.references :virtual_account_product, null: false, foreign_key: { to_table: :dscf_banking_virtual_account_products }
6
+ t.references :application, null: false, foreign_key: { to_table: :dscf_banking_applications }
7
+ t.string :name, null: false
8
+ t.integer :status, default: 0
9
+ t.date :activation_date
10
+ t.date :closure_date
11
+ t.jsonb :account_properties, default: {}
12
+ t.decimal :current_balance, precision: 20, scale: 4, default: 0
13
+ t.decimal :available_balance, precision: 20, scale: 4, default: 0
14
+ t.decimal :minimum_balance, precision: 20, scale: 4, default: 0
15
+ t.string :currency, null: false, default: 'ETB'
16
+ t.boolean :active, default: true
17
+
18
+ t.timestamps
19
+ end
20
+ end
21
+ end
@@ -1,5 +1,5 @@
1
1
  module Dscf
2
2
  module Banking
3
- VERSION = "0.1.0"
3
+ VERSION = "0.1.1"
4
4
  end
5
5
  end
@@ -0,0 +1,51 @@
1
+ FactoryBot.define do
2
+ factory :dscf_banking_account, class: "Dscf::Banking::Account" do
3
+ association :virtual_account_product, factory: :virtual_account_product
4
+ association :application, factory: :application
5
+
6
+ name { "Test Account" }
7
+ currency { "ETB" }
8
+ current_balance { 0 }
9
+ available_balance { 0 }
10
+ minimum_balance { 0 }
11
+ status { :draft }
12
+ active { true }
13
+ account_properties { {} }
14
+
15
+ trait :active do
16
+ status { :active }
17
+ activation_date { Date.current }
18
+ end
19
+
20
+ trait :suspended do
21
+ status { :suspended }
22
+ end
23
+
24
+ trait :closed do
25
+ status { :closed }
26
+ active { false }
27
+ closure_date { Date.current }
28
+ end
29
+
30
+ trait :with_balance do
31
+ current_balance { 1000 }
32
+ available_balance { 1000 }
33
+ minimum_balance { 100 }
34
+ end
35
+ end
36
+
37
+ # Alias for shared spec compatibility
38
+ factory :account, class: "Dscf::Banking::Account" do
39
+ association :virtual_account_product, factory: :virtual_account_product
40
+ association :application, factory: :application
41
+
42
+ name { "Test Account" }
43
+ currency { "ETB" }
44
+ current_balance { 0 }
45
+ available_balance { 0 }
46
+ minimum_balance { 0 }
47
+ status { :draft }
48
+ active { true }
49
+ account_properties { {} }
50
+ end
51
+ end
@@ -0,0 +1,64 @@
1
+ FactoryBot.define do
2
+ factory :application, class: "Dscf::Banking::Application" do
3
+ association :user
4
+ association :virtual_account_product
5
+ applicant_type { :individual }
6
+ status { :draft }
7
+
8
+ form_data do
9
+ {
10
+ first_name: Faker::Name.first_name,
11
+ last_name: Faker::Name.last_name,
12
+ date_of_birth: Faker::Date.birthday(min_age: 18, max_age: 80).to_s,
13
+ nationality: "Ethiopian",
14
+ phone: Faker::PhoneNumber.phone_number,
15
+ address: Faker::Address.full_address
16
+ }
17
+ end
18
+ submitted_at { nil }
19
+ completed_at { nil }
20
+ rejection_reason { nil }
21
+ assigned_kyc_officer { nil }
22
+ assigned_branch_manager { nil }
23
+
24
+ trait :business do
25
+ applicant_type { :business }
26
+ application_type { :current }
27
+ form_data do
28
+ {
29
+ business_name: Faker::Company.name,
30
+ tin_number: Faker::Number.number(digits: 10).to_s,
31
+ business_type: "Limited Company",
32
+ contact_person: Faker::Name.name,
33
+ phone: Faker::PhoneNumber.phone_number,
34
+ address: Faker::Address.full_address
35
+ }
36
+ end
37
+ end
38
+
39
+ trait :submitted do
40
+ status { :submitted }
41
+ submitted_at { 1.day.ago }
42
+ end
43
+
44
+ trait :under_review do
45
+ status { :under_review }
46
+ submitted_at { 2.days.ago }
47
+ association :assigned_kyc_officer, factory: [ :user, :dscf_core ]
48
+ end
49
+
50
+ trait :approved do
51
+ status { :approved }
52
+ submitted_at { 3.days.ago }
53
+ association :assigned_kyc_officer, factory: [ :user, :dscf_core ]
54
+ association :assigned_branch_manager, factory: [ :user, :dscf_core ]
55
+ end
56
+
57
+ trait :rejected do
58
+ status { :rejected }
59
+ submitted_at { 3.days.ago }
60
+ rejection_reason { "Incomplete documentation" }
61
+ association :assigned_kyc_officer, factory: [ :user, :dscf_core ]
62
+ end
63
+ end
64
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dscf-banking
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eyosiyas Mekbib
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-08-31 00:00:00.000000000 Z
10
+ date: 2025-09-13 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: rails
@@ -439,7 +439,9 @@ files:
439
439
  - MIT-LICENSE
440
440
  - README.md
441
441
  - Rakefile
442
+ - app/controllers/dscf/banking/accounts_controller.rb
442
443
  - app/controllers/dscf/banking/application_controller.rb
444
+ - app/controllers/dscf/banking/applications_controller.rb
443
445
  - app/controllers/dscf/banking/interest_configurations_controller.rb
444
446
  - app/controllers/dscf/banking/interest_rate_tiers_controller.rb
445
447
  - app/controllers/dscf/banking/interest_rate_types_controller.rb
@@ -449,6 +451,8 @@ files:
449
451
  - app/jobs/dscf/banking/application_job.rb
450
452
  - app/mailers/dscf/banking/application_mailer.rb
451
453
  - app/models/concerns/dscf/banking/auditable.rb
454
+ - app/models/dscf/banking/account.rb
455
+ - app/models/dscf/banking/application.rb
452
456
  - app/models/dscf/banking/application_record.rb
453
457
  - app/models/dscf/banking/interest_configuration.rb
454
458
  - app/models/dscf/banking/interest_rate_tier.rb
@@ -457,12 +461,15 @@ files:
457
461
  - app/models/dscf/banking/product_audit_log.rb
458
462
  - app/models/dscf/banking/product_category.rb
459
463
  - app/models/dscf/banking/virtual_account_product.rb
464
+ - app/serializers/dscf/banking/account_serializer.rb
465
+ - app/serializers/dscf/banking/application_serializer.rb
460
466
  - app/serializers/dscf/banking/interest_configuration_serializer.rb
461
467
  - app/serializers/dscf/banking/interest_rate_tier_serializer.rb
462
468
  - app/serializers/dscf/banking/interest_rate_type_serializer.rb
463
469
  - app/serializers/dscf/banking/product_approval_serializer.rb
464
470
  - app/serializers/dscf/banking/product_category_serializer.rb
465
471
  - app/serializers/dscf/banking/virtual_account_product_serializer.rb
472
+ - app/services/dscf/banking/account_creation_service.rb
466
473
  - config/routes.rb
467
474
  - db/migrate/20250830211002_create_dscf_banking_product_categories.rb
468
475
  - db/migrate/20250830211027_create_dscf_banking_interest_rate_types.rb
@@ -473,10 +480,14 @@ files:
473
480
  - db/migrate/20250831082356_create_dscf_banking_product_approvals.rb
474
481
  - db/migrate/20250831083907_create_dscf_banking_product_audit_logs.rb
475
482
  - db/migrate/20250831084706_allow_null_virtual_account_product_id_in_product_audit_logs.rb
483
+ - db/migrate/20250912193134_create_dscf_banking_applications.rb
484
+ - db/migrate/20250912203527_create_dscf_banking_accounts.rb
476
485
  - lib/dscf/banking.rb
477
486
  - lib/dscf/banking/engine.rb
478
487
  - lib/dscf/banking/version.rb
479
488
  - lib/tasks/dscf/banking_tasks.rake
489
+ - spec/factories/dscf/banking/accounts.rb
490
+ - spec/factories/dscf/banking/applications.rb
480
491
  - spec/factories/dscf/banking/interest_configurations.rb
481
492
  - spec/factories/dscf/banking/interest_rate_tiers.rb
482
493
  - spec/factories/dscf/banking/interest_rate_types.rb