dscf-banking 0.3.6 → 0.3.7

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 (30) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/dscf/banking/accounts_controller.rb +6 -12
  3. data/app/controllers/dscf/banking/documents_controller.rb +4 -4
  4. data/app/controllers/dscf/banking/interest_configurations_controller.rb +3 -5
  5. data/app/controllers/dscf/banking/transactions_controller.rb +1 -1
  6. data/app/controllers/dscf/banking/virtual_account_products_controller.rb +4 -4
  7. data/app/controllers/dscf/banking/vouchers_controller.rb +133 -0
  8. data/app/models/dscf/banking/account.rb +4 -1
  9. data/app/models/dscf/banking/interest_configuration.rb +8 -117
  10. data/app/models/dscf/banking/virtual_account_product.rb +1 -2
  11. data/app/models/dscf/banking/voucher.rb +76 -0
  12. data/app/models/dscf/banking/voucher_redemption.rb +27 -0
  13. data/app/serializers/dscf/banking/account_serializer.rb +3 -2
  14. data/app/serializers/dscf/banking/document_serializer.rb +3 -9
  15. data/app/serializers/dscf/banking/interest_configuration_serializer.rb +0 -1
  16. data/app/serializers/dscf/banking/voucher_redemption_serializer.rb +10 -0
  17. data/app/serializers/dscf/banking/voucher_serializer.rb +20 -0
  18. data/app/services/dscf/banking/voucher_service.rb +317 -0
  19. data/config/routes.rb +1 -0
  20. data/db/migrate/20260210120000_create_dscf_banking_vouchers.rb +23 -0
  21. data/db/migrate/20260210120010_create_dscf_banking_voucher_redemptions.rb +16 -0
  22. data/db/seeds.rb +30 -49
  23. data/lib/dscf/banking/version.rb +1 -1
  24. data/spec/factories/dscf/banking/accounts.rb +2 -0
  25. data/spec/factories/dscf/banking/interest_configurations.rb +14 -42
  26. data/spec/factories/dscf/banking/interest_rate_types.rb +1 -1
  27. data/spec/factories/dscf/banking/voucher_redemptions.rb +9 -0
  28. data/spec/factories/dscf/banking/vouchers.rb +14 -0
  29. metadata +14 -19
  30. data/db/seeds/interest_rate_types.rb +0 -38
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f5ee5ccda8af113288e3eea6f69ba2a24b71d980850d72b25efb187b4f82579b
4
- data.tar.gz: ab2d16dcde12321a0a18da6824e5f5788c10ca8aba568eb138085440187c3976
3
+ metadata.gz: 1d9aebfb57294bdeee3240fe4079565174e97a172b44aaf93c4d93f3be94573d
4
+ data.tar.gz: f7acfa8939c35b2ce39f99a787772712ee886be3ed89326247948edf6f4b8a9e
5
5
  SHA512:
6
- metadata.gz: e68fcc9ad5dee13a9589181cede9394c2854c32d14db75e76618d523a2c8ec82a412acb867a62281477197e143a845b3d68299fe254d446e0158a059fe8f9bde
7
- data.tar.gz: 99cdc4974f9c5068416f14c3fba844c3e7b023a1da84b0e42838f9aa88d0c4bc283824225344297f5afac92f4d7dd031d20390384d3538abcb9b5e8d6ad46c31
6
+ metadata.gz: 714c5cdb80e79dea3fd95842f9ef2ddb5e1f39c49af9f08ffee40625157ec2147fb0676430316885f8c28534811982a48ada4c471aef0c91a338d9c3fc068b5a
7
+ data.tar.gz: b1b6079ab0ad3d70f2c9c1076f70b06f6cefe57c118a1fa001710319a29054808bede0b95dfada63702968a6310ca74190d7013444c72889c7a1eca8ac034255
@@ -30,18 +30,12 @@ module Dscf::Banking
30
30
 
31
31
  def full_name
32
32
  account = Dscf::Banking::Account.find_by(account_number: params[:id])
33
- if account && account.application && account.application.user
34
- user = account.application.user
35
- profile = user.respond_to?(:user_profile) ? user.user_profile : nil
36
- if profile
37
- full_name = [ profile.first_name, profile.middle_name, profile.last_name ].compact.join(" ")
38
- render json: { success: true, data: { full_name: full_name } }
39
- else
40
- render json: { success: false, error: "User profile not found" }, status: :not_found
41
- end
42
- else
43
- render json: { success: false, error: "Account not found" }, status: :not_found
44
- end
33
+ return render json: { success: false, error: "Account not found" }, status: :not_found unless account
34
+
35
+ full_name = account.name.to_s.strip
36
+ full_name = "Unnamed" if full_name.empty?
37
+
38
+ render json: { success: true, data: { full_name: full_name } }
45
39
  end
46
40
 
47
41
  def show
@@ -8,7 +8,7 @@ module Dscf::Banking
8
8
  super do
9
9
  documents = @application.documents
10
10
  options = { each_serializer: DocumentSerializer }
11
- [ documents, options ]
11
+ [documents, options]
12
12
  end
13
13
  end
14
14
 
@@ -16,17 +16,17 @@ module Dscf::Banking
16
16
  super do
17
17
  document = @application.documents.find(params[:id])
18
18
  options = { serializer: DocumentSerializer }
19
- [ document, options ]
19
+ [document, options]
20
20
  end
21
21
  end
22
22
 
23
23
  def create
24
24
  document = @application.documents.build(model_params)
25
-
25
+
26
26
  if document.save
27
27
  # Attach file if provided
28
28
  document.files.attach(params[:document][:file]) if params[:document][:file].present?
29
-
29
+
30
30
  render json: {
31
31
  success: true,
32
32
  data: DocumentSerializer.new(document).as_json
@@ -24,7 +24,7 @@ module Dscf::Banking
24
24
  end
25
25
 
26
26
  def eager_loaded_associations
27
- [ :virtual_account_product, :interest_rate_type, :interest_rate_tiers ]
27
+ [ :virtual_account_product, :interest_rate_type ]
28
28
  end
29
29
 
30
30
  def allowed_order_columns
@@ -33,10 +33,8 @@ module Dscf::Banking
33
33
 
34
34
  def default_serializer_includes
35
35
  {
36
- index: [ :virtual_account_product, :interest_rate_type, :interest_rate_tiers ],
37
- show: [ :virtual_account_product, :interest_rate_type, :interest_rate_tiers ],
38
- create: [ :virtual_account_product, :interest_rate_type, :interest_rate_tiers ],
39
- update: [ :virtual_account_product, :interest_rate_type, :interest_rate_tiers ]
36
+ virtual_account_product: {},
37
+ interest_rate_type: {}
40
38
  }
41
39
  end
42
40
  end
@@ -6,7 +6,7 @@ module Dscf::Banking
6
6
  render json: {
7
7
  success: false,
8
8
  error: "Transaction not found",
9
- errors: [ "Transaction with ID #{params[:id]} not found" ]
9
+ errors: ["Transaction with ID #{params[:id]} not found"]
10
10
  }, status: :not_found
11
11
  end
12
12
 
@@ -83,10 +83,10 @@ module Dscf::Banking
83
83
 
84
84
  def default_serializer_includes
85
85
  {
86
- index: [ :product_category, :created_by, :approved_by, reviews: { reviewed_by: :user_profile } ],
87
- show: [ :product_category, :created_by, :approved_by, reviews: { reviewed_by: :user_profile } ],
88
- create: [ :reviews ],
89
- update: [ :product_category, :created_by, :approved_by, reviews: { reviewed_by: :user_profile } ]
86
+ index: [:product_category, :created_by, :approved_by, reviews: { reviewed_by: :user_profile }],
87
+ show: [:product_category, :created_by, :approved_by, reviews: { reviewed_by: :user_profile }],
88
+ create: [:reviews],
89
+ update: [:product_category, :created_by, :approved_by, reviews: { reviewed_by: :user_profile }]
90
90
  }
91
91
  end
92
92
  end
@@ -0,0 +1,133 @@
1
+ module Dscf
2
+ module Banking
3
+ class VouchersController < ApplicationController
4
+ include Dscf::Core::Common
5
+
6
+ def create
7
+ parent_account = Dscf::Banking::Account.find_by(account_number: model_params[:parent_account_number])
8
+
9
+ unless parent_account
10
+ return render_error(errors: "Parent account not found", status: :not_found)
11
+ end
12
+
13
+ service = Dscf::Banking::VoucherService.new
14
+ service.generate_voucher(
15
+ parent_account: parent_account,
16
+ amount: model_params[:amount],
17
+ recipient_mobile: model_params[:recipient_mobile],
18
+ recipient_name: model_params[:recipient_name],
19
+ message: model_params[:message],
20
+ expires_at: model_params[:expires_at]
21
+ )
22
+
23
+ if service.success?
24
+ render_success(data: service.voucher, serializer_options: { include: default_serializer_includes[:default] }, status: :created)
25
+ else
26
+ render_error(errors: service.errors, status: :unprocessable_entity)
27
+ end
28
+ end
29
+
30
+ def redeem
31
+ service = Dscf::Banking::VoucherService.new
32
+ destination_account = nil
33
+
34
+ if redeem_params[:destination_account_number].present?
35
+ destination_account = Dscf::Banking::Account.find_by(account_number: redeem_params[:destination_account_number])
36
+ unless destination_account
37
+ return render_error(errors: "Destination account not found", status: :not_found)
38
+ end
39
+ end
40
+
41
+ service.redeem_voucher(
42
+ code: redeem_params[:code] || params[:code],
43
+ amount: redeem_params[:amount],
44
+ recipient_mobile: redeem_params[:recipient_mobile],
45
+ destination_account: destination_account
46
+ )
47
+
48
+ if service.success?
49
+ render_success(
50
+ data: {
51
+ voucher: service.voucher,
52
+ redemption: service.redemption
53
+ },
54
+ serializer_options: {
55
+ voucher: { include: default_serializer_includes[:default] },
56
+ redemption: { include: [ :destination_account ] }
57
+ }
58
+ )
59
+ else
60
+ render_error(errors: service.errors, status: :unprocessable_entity)
61
+ end
62
+ end
63
+
64
+ def show
65
+ voucher = Dscf::Banking::Voucher.find_by(code: params[:id].to_s.strip.upcase)
66
+ return render_error(errors: "Voucher not found", status: :not_found) unless voucher
67
+
68
+ if voucher.active? && voucher.expired?
69
+ Dscf::Banking::VoucherService.new.expire_voucher(voucher)
70
+ voucher.reload
71
+ end
72
+
73
+ render_success(data: voucher, serializer_options: { include: default_serializer_includes[:default] })
74
+ end
75
+
76
+ def cancel
77
+ service = Dscf::Banking::VoucherService.new
78
+ service.cancel_voucher(code: params[:code])
79
+
80
+ if service.success?
81
+ render_success(data: service.voucher, serializer_options: { include: default_serializer_includes[:default] })
82
+ else
83
+ render_error(errors: service.errors, status: :unprocessable_entity)
84
+ end
85
+ end
86
+
87
+ def account_vouchers
88
+ account = Dscf::Banking::Account.find(params[:account_id])
89
+ vouchers = account.vouchers.order(created_at: :desc)
90
+
91
+ render_success(data: vouchers, serializer_options: { include: default_serializer_includes[:default] })
92
+ rescue ActiveRecord::RecordNotFound
93
+ render_error(errors: "Account not found", status: :not_found)
94
+ end
95
+
96
+ private
97
+
98
+ def model_params
99
+ params.require(:voucher).permit(
100
+ :parent_account_number,
101
+ :amount,
102
+ :recipient_mobile,
103
+ :recipient_name,
104
+ :message,
105
+ :expires_at
106
+ )
107
+ end
108
+
109
+ def redeem_params
110
+ params.require(:redemption).permit(
111
+ :code,
112
+ :amount,
113
+ :recipient_mobile,
114
+ :destination_account_number
115
+ )
116
+ end
117
+
118
+ def eager_loaded_associations
119
+ []
120
+ end
121
+
122
+ def allowed_order_columns
123
+ %w[id code status amount remaining_amount recipient_mobile created_at updated_at]
124
+ end
125
+
126
+ def default_serializer_includes
127
+ {
128
+ default: [ :parent_account, :redemptions ]
129
+ }
130
+ end
131
+ end
132
+ end
133
+ end
@@ -3,6 +3,9 @@ module Dscf::Banking
3
3
  belongs_to :virtual_account_product, optional: true
4
4
  belongs_to :application, optional: true
5
5
 
6
+ has_many :vouchers, class_name: "Dscf::Banking::Voucher", foreign_key: :parent_account_id, dependent: :restrict_with_error
7
+ has_many :voucher_redemptions, through: :vouchers, class_name: "Dscf::Banking::VoucherRedemption"
8
+
6
9
  enum :status, {
7
10
  draft: 0,
8
11
  pending_activation: 1,
@@ -16,7 +19,7 @@ module Dscf::Banking
16
19
  validates :name, presence: true
17
20
  validates :currency, presence: true
18
21
  validates :current_balance, :available_balance, :minimum_balance,
19
- numericality: { greater_than_or_equal_to: 0 }
22
+ numericality: { greater_than_or_equal_to: 0 }
20
23
  validates :system_account, inclusion: { in: [ true, false ] }
21
24
  validate :system_account_associations
22
25
 
@@ -2,25 +2,19 @@ module Dscf::Banking
2
2
  class InterestConfiguration < ApplicationRecord
3
3
  belongs_to :interest_rate_type, class_name: "Dscf::Banking::InterestRateType"
4
4
  belongs_to :virtual_account_product, class_name: "Dscf::Banking::VirtualAccountProduct"
5
- has_many :interest_rate_tiers, class_name: "Dscf::Banking::InterestRateTier", foreign_key: :interest_config_id, dependent: :destroy
5
+ has_many :interest_rate_tiers, class_name: "Dscf::Banking::InterestRateTier", dependent: :destroy
6
6
 
7
- validates :annual_interest_rate, presence: true, numericality: { greater_than: 0, less_than_or_equal_to: 1 }, unless: :interest_free?
8
- validates :annual_interest_rate, numericality: { greater_than_or_equal_to: 0, less_than_or_equal_to: 1 }, if: :interest_free?, allow_nil: true
7
+ validates :annual_interest_rate, presence: true, numericality: { greater_than: 0, less_than_or_equal_to: 1 }
9
8
  validates :income_tax_rate, presence: true, numericality: { greater_than_or_equal_to: 0, less_than_or_equal_to: 1 }
10
9
  validates :minimum_balance_for_interest, presence: true, numericality: { greater_than_or_equal_to: 0 }
11
- validates :calculation_method, presence: true, unless: :interest_free?
12
- validates :interest_basis, presence: true, unless: :interest_free?
13
- validates :accrual_frequency, presence: true, unless: :interest_free?
14
- validates :rounding_rule, presence: true, unless: :interest_free?
15
- validates :calculation_timing, presence: true, unless: :interest_free?
16
- validates :is_active, inclusion: { in: [ true, false ] }
10
+ validates :calculation_method, presence: true
17
11
 
12
+ validates :interest_basis, presence: true
13
+ validates :accrual_frequency, presence: true
14
+ validates :rounding_rule, presence: true
15
+ validates :calculation_timing, presence: true
16
+ validates :is_active, inclusion: { in: [ true, false ] }
18
17
  validate :promotional_dates_consistency
19
- validate :rate_type_specific_validations
20
- validate :tiers_only_for_variable_rate
21
- validate :interest_rate_type_requirements
22
-
23
- before_validation :set_interest_basis_from_accrual_frequency
24
18
 
25
19
  enum :calculation_method, {
26
20
  simple: 0,
@@ -63,33 +57,6 @@ module Dscf::Banking
63
57
  scope :promotional, -> { where.not(promotional_start_date: nil, promotional_end_date: nil) }
64
58
  scope :current_promotional, -> { where("promotional_start_date <= ? AND promotional_end_date >= ?", Date.current, Date.current) }
65
59
 
66
- def self.ransackable_attributes(auth_object = nil)
67
- %w[id virtual_account_product_id interest_rate_type_id annual_interest_rate income_tax_rate
68
- minimum_balance_for_interest calculation_method compounding_period interest_basis
69
- accrual_frequency rounding_rule promotional_start_date promotional_end_date is_active
70
- created_at updated_at]
71
- end
72
-
73
- def self.ransackable_associations(auth_object = nil)
74
- %w[virtual_account_product interest_rate_type interest_rate_tiers]
75
- end
76
-
77
- def interest_free?
78
- interest_rate_type&.code == "INTEREST_FREE"
79
- end
80
-
81
- def fixed_rate?
82
- interest_rate_type&.code == "FIXED"
83
- end
84
-
85
- def variable_rate?
86
- interest_rate_type&.code == "VARIABLE"
87
- end
88
-
89
- def promotional_rate?
90
- interest_rate_type&.code == "PROMOTIONAL"
91
- end
92
-
93
60
  private
94
61
 
95
62
  def promotional_dates_consistency
@@ -114,81 +81,5 @@ module Dscf::Banking
114
81
  errors.add(:calculation_day_of_month, "must be specified for annual accrual") if calculation_day_of_month.blank?
115
82
  end
116
83
  end
117
-
118
- def rate_type_specific_validations
119
- return if interest_rate_type.blank?
120
-
121
- case interest_rate_type.code
122
- when "INTEREST_FREE"
123
- validate_interest_free
124
- when "FIXED"
125
- validate_fixed_rate
126
- when "VARIABLE"
127
- validate_variable_rate
128
- when "PROMOTIONAL"
129
- validate_promotional_rate
130
- end
131
- end
132
-
133
- def validate_interest_free
134
- if annual_interest_rate.present? && annual_interest_rate > 0
135
- errors.add(:annual_interest_rate, "must be 0 for interest-free accounts")
136
- end
137
- end
138
-
139
- def validate_fixed_rate
140
- if annual_interest_rate.blank? || annual_interest_rate <= 0
141
- errors.add(:annual_interest_rate, "must be greater than 0 for fixed rate")
142
- end
143
- end
144
-
145
- def validate_variable_rate
146
- if annual_interest_rate.blank? || annual_interest_rate <= 0
147
- errors.add(:annual_interest_rate, "must be greater than 0 for variable rate")
148
- end
149
- end
150
-
151
- def validate_promotional_rate
152
- if promotional_start_date.blank?
153
- errors.add(:promotional_start_date, "is required for promotional rate")
154
- end
155
- if promotional_end_date.blank?
156
- errors.add(:promotional_end_date, "is required for promotional rate")
157
- end
158
- if annual_interest_rate.blank? || annual_interest_rate <= 0
159
- errors.add(:annual_interest_rate, "must be greater than 0 for promotional rate")
160
- end
161
- end
162
-
163
- def tiers_only_for_variable_rate
164
- return if interest_rate_type.blank?
165
- return unless persisted? || interest_rate_tiers.loaded?
166
-
167
- if !variable_rate? && interest_rate_tiers.any?
168
- errors.add(:base, "Interest rate tiers can only be used with variable rate type")
169
- end
170
- end
171
-
172
- def interest_rate_type_requirements
173
- return if interest_rate_type.blank?
174
- return unless persisted?
175
-
176
- if variable_rate? && interest_rate_tiers.empty?
177
- errors.add(:base, "Variable rate type requires at least one interest rate tier")
178
- end
179
- end
180
-
181
- def set_interest_basis_from_accrual_frequency
182
- return if accrual_frequency.blank?
183
- return if interest_free?
184
- return if interest_basis.present?
185
-
186
- case accrual_frequency
187
- when "daily"
188
- self.interest_basis = :actual_365
189
- when "monthly", "quarterly", "annually"
190
- self.interest_basis = :thirty_360
191
- end
192
- end
193
84
  end
194
85
  end
@@ -19,7 +19,6 @@ module Dscf::Banking
19
19
 
20
20
  has_many :product_approvals, class_name: "Dscf::Banking::ProductApproval", dependent: :destroy
21
21
  has_many :product_audit_logs, class_name: "Dscf::Banking::ProductAuditLog", dependent: :destroy
22
- has_many :interest_configurations, class_name: "Dscf::Banking::InterestConfiguration", dependent: :destroy
23
22
 
24
23
  validates :product_code, presence: true, uniqueness: { case_sensitive: true }, length: { maximum: 50 }
25
24
  validates :product_name, presence: true, length: { maximum: 200 }
@@ -43,7 +42,7 @@ module Dscf::Banking
43
42
  end
44
43
 
45
44
  def self.ransackable_associations(auth_object = nil)
46
- %w[product_category created_by approved_by reviews interest_configurations]
45
+ %w[product_category created_by approved_by reviews]
47
46
  end
48
47
 
49
48
  before_validation :strip_whitespace
@@ -0,0 +1,76 @@
1
+ module Dscf
2
+ module Banking
3
+ class Voucher < ApplicationRecord
4
+ self.table_name = "dscf_banking_vouchers"
5
+
6
+ belongs_to :parent_account, class_name: "Dscf::Banking::Account"
7
+ has_many :redemptions, class_name: "Dscf::Banking::VoucherRedemption", dependent: :restrict_with_error
8
+
9
+ enum :status, {
10
+ pending: 0,
11
+ active: 1,
12
+ redeemed: 2,
13
+ expired: 3,
14
+ cancelled: 4
15
+ }
16
+
17
+ validates :parent_account, presence: true
18
+ validates :amount, presence: true, numericality: { greater_than: 0 }
19
+ validates :remaining_amount, presence: true, numericality: { greater_than_or_equal_to: 0 }
20
+ validates :currency, presence: true
21
+ validates :code, presence: true, uniqueness: { case_sensitive: false }
22
+ validates :recipient_mobile, presence: true
23
+ validate :remaining_amount_not_exceed_amount
24
+ validate :expires_at_in_future, if: -> { expires_at.present? }
25
+
26
+ before_validation :set_defaults, on: :create
27
+ before_validation :normalize_code, if: -> { code.present? }
28
+
29
+ scope :by_status, ->(status) { where(status: status) }
30
+ scope :active_now, -> { where(status: :active).where("expires_at IS NULL OR expires_at > ?", Time.current) }
31
+ scope :expired_now, -> { where(status: :active).where("expires_at IS NOT NULL AND expires_at <= ?", Time.current) }
32
+
33
+ def expired?
34
+ expires_at.present? && expires_at <= Time.current
35
+ end
36
+
37
+ def fully_redeemed?
38
+ remaining_amount.to_f.zero?
39
+ end
40
+
41
+ def mark_expired!
42
+ update!(status: :expired) if expired? && !expired_status?
43
+ end
44
+
45
+ def expired_status?
46
+ status == "expired"
47
+ end
48
+
49
+ private
50
+
51
+ def set_defaults
52
+ self.currency ||= parent_account&.currency
53
+ self.remaining_amount = amount if remaining_amount.nil? && amount
54
+ self.status ||= :pending
55
+ end
56
+
57
+ def normalize_code
58
+ self.code = code.to_s.strip.upcase
59
+ end
60
+
61
+ def remaining_amount_not_exceed_amount
62
+ return if amount.nil? || remaining_amount.nil?
63
+
64
+ if remaining_amount > amount
65
+ errors.add(:remaining_amount, "cannot exceed voucher amount")
66
+ end
67
+ end
68
+
69
+ def expires_at_in_future
70
+ if expires_at <= Time.current
71
+ errors.add(:expires_at, "must be in the future")
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,27 @@
1
+ module Dscf
2
+ module Banking
3
+ class VoucherRedemption < ApplicationRecord
4
+ self.table_name = "dscf_banking_voucher_redemptions"
5
+
6
+ belongs_to :voucher, class_name: "Dscf::Banking::Voucher"
7
+ belongs_to :destination_account, class_name: "Dscf::Banking::Account", optional: true
8
+
9
+ validates :voucher, presence: true
10
+ validates :amount, presence: true, numericality: { greater_than: 0 }
11
+ validates :recipient_mobile, presence: true
12
+ validates :currency, presence: true
13
+ validates :redeemed_at, presence: true
14
+
15
+ before_validation :set_defaults, on: :create
16
+
17
+ scope :by_voucher, ->(voucher_id) { where(voucher_id: voucher_id) }
18
+
19
+ private
20
+
21
+ def set_defaults
22
+ self.currency ||= voucher&.currency
23
+ self.recipient_mobile ||= voucher&.recipient_mobile
24
+ end
25
+ end
26
+ end
27
+ end
@@ -1,11 +1,12 @@
1
1
  module Dscf::Banking
2
2
  class AccountSerializer < ActiveModel::Serializer
3
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
4
+ :account_properties, :current_balance, :available_balance, :minimum_balance,
5
+ :currency, :active, :created_at, :updated_at
6
6
 
7
7
  belongs_to :virtual_account_product, serializer: VirtualAccountProductSerializer
8
8
 
9
9
  attribute :application_id
10
+ attribute :system_account
10
11
  end
11
12
  end
@@ -1,14 +1,8 @@
1
1
  module Dscf::Banking
2
2
  class DocumentSerializer < ActiveModel::Serializer
3
- attributes :id, :document_type, :is_verified, :verified_at, :metadata, :file_urls, :created_at, :updated_at,
4
- :documentable_type, :documentable_id, :documentable
3
+ attributes :id, :document_type, :is_verified, :verified_at, :metadata, :file_urls, :created_at, :updated_at
5
4
 
6
- def documentable
7
- {
8
- type: object.documentable_type,
9
- id: object.documentable_id
10
- }
11
- end
5
+ belongs_to :documentable, polymorphic: true
12
6
 
13
7
  def file_urls
14
8
  return [] unless object.files.attached?
@@ -22,7 +16,7 @@ module Dscf::Banking
22
16
  object.files.map(&:url)
23
17
  end
24
18
  end
25
- rescue StandardError
19
+ rescue
26
20
  []
27
21
  end
28
22
  end
@@ -7,6 +7,5 @@ module Dscf::Banking
7
7
 
8
8
  belongs_to :virtual_account_product, serializer: VirtualAccountProductSerializer
9
9
  belongs_to :interest_rate_type, serializer: InterestRateTypeSerializer
10
- has_many :interest_rate_tiers, serializer: InterestRateTierSerializer
11
10
  end
12
11
  end
@@ -0,0 +1,10 @@
1
+ module Dscf
2
+ module Banking
3
+ class VoucherRedemptionSerializer < ActiveModel::Serializer
4
+ attributes :id, :voucher_id, :destination_account_id, :amount, :currency,
5
+ :recipient_mobile, :redeemed_at, :created_at, :updated_at
6
+
7
+ belongs_to :destination_account, serializer: AccountSerializer
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,20 @@
1
+ module Dscf
2
+ module Banking
3
+ class VoucherSerializer < ActiveModel::Serializer
4
+ attributes :id, :parent_account_id, :code, :status, :amount, :remaining_amount,
5
+ :currency, :recipient_mobile, :recipient_name, :message, :expires_at,
6
+ :redeemed_at, :created_at, :updated_at
7
+
8
+ attribute :amount do
9
+ object.amount.to_f
10
+ end
11
+
12
+ attribute :remaining_amount do
13
+ object.remaining_amount.to_f
14
+ end
15
+
16
+ belongs_to :parent_account, serializer: AccountSerializer
17
+ has_many :redemptions, serializer: VoucherRedemptionSerializer
18
+ end
19
+ end
20
+ end