dscf-core 0.3.6 → 0.3.8

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: c79b0bd46b44ace100520a0a873e5a6dce32e9f13caf6c72c5ea7a729e1db870
4
- data.tar.gz: 6715fc56d379b5600c71a4a78cccd4991a381f9a9a5d8ab0a80d5bc78b4c468d
3
+ metadata.gz: ca2cb2e351f124278aa1855d908cb84dea04a3842e1216b8485f6d8a73878667
4
+ data.tar.gz: 8563fbf9759f19d08c1699cb35d723cd1ee7cec928e7cbcf5d840880a0404491
5
5
  SHA512:
6
- metadata.gz: a8b2df9c292d42b1331e30f05af007a2e45d416b4af9863fba943e329130a8705951cbf407c96fe014d0d2d4c9112abcafca38be10a47d8b24ac9e48ccdcce7e
7
- data.tar.gz: 8268c64be459eacf7f1afa2c0f80b6b5370fcaad0d2f95f9744fde90c7e7e70add2a5f345fd70b53bf5eb1f1852f01f7261576ea623dee23308f2230c61623bc
6
+ metadata.gz: dbf4de0d1af84c42cd807be0c0ee32d1727f1f7fe726d28648c71b174d3d16d4a1a825fd04bcb8480b8c07a4f1841947c2b2d3ca98cc9f65ee59a56373b910b5
7
+ data.tar.gz: 775cb2504183bb0579586918e5a11b25e7dfe0d7120bffd02e17fe391e82cdf5dfadd4a2e98f93aff63be4eea6b50a48d5695562ccd508e92dbe075b0fba9c42
@@ -13,6 +13,9 @@ module Dscf
13
13
  end
14
14
 
15
15
  def authorize_action!
16
+ # Only perform automatic before_action authorization for standard REST actions
17
+ return skip_authorization unless %w[index show create update destroy].include?(action_name)
18
+
16
19
  policy_target = resolve_policy_target
17
20
  return skip_authorization unless policy_target
18
21
 
@@ -10,10 +10,12 @@ module Dscf
10
10
  included do
11
11
  before_action :set_clazz
12
12
  before_action :set_object, only: %i[show update]
13
+ skip_before_action :authorize_action!, raise: false
14
+ before_action :authorize_action!
13
15
  end
14
16
 
15
17
  def index
16
- authorize @clazz.new, :index?
18
+ authorize @clazz.new, "#{action_name}?"
17
19
 
18
20
  data = nil
19
21
  options = {}
@@ -3,13 +3,29 @@ module Dscf
3
3
  module RoleAssignable
4
4
  extend ActiveSupport::Concern
5
5
 
6
- def assign_default_role(user)
7
- role = Role.find_or_create_by!(code: "USER") do |r|
8
- r.name = "User"
6
+ def assign_default_role(user, role_code = "USER")
7
+ role = Role.find_or_create_by!(code: role_code) do |r|
8
+ r.name = role_code.titleize
9
+ r.active = true
9
10
  end
10
11
 
12
+ copy_user_role_permissions(role) unless role_code == "USER"
13
+
11
14
  UserRole.find_or_create_by!(user: user, role: role)
12
15
  end
16
+
17
+ private
18
+
19
+ def copy_user_role_permissions(role)
20
+ return if role.permissions.any?
21
+
22
+ user_role = Role.find_by(code: "USER")
23
+ return unless user_role
24
+
25
+ user_role.permissions.each do |permission|
26
+ RolePermission.find_or_create_by!(role: role, permission: permission)
27
+ end
28
+ end
13
29
  end
14
30
  end
15
31
  end
@@ -47,11 +47,18 @@ module Dscf
47
47
 
48
48
  ActiveRecord::Base.transaction do
49
49
  if user.save
50
- assign_default_role(user)
50
+ role_code = if params[:agent].present?
51
+ "AGENT"
52
+ elsif params[:retailer].present?
53
+ "RETAILER"
54
+ else
55
+ "USER"
56
+ end
57
+ assign_default_role(user, role_code)
51
58
 
52
59
  # Optionally create marketplace records when onboarding via mobile app
53
- create_agent_from_signup! if params[:agent].present?
54
- create_retailer_from_signup! if params[:retailer].present?
60
+ create_agent_from_signup!(user) if params[:agent].present?
61
+ create_retailer_from_signup!(user) if params[:retailer].present?
55
62
 
56
63
  user_with_includes = User.includes(roles: :permissions, user_profile: {}).find(user.id)
57
64
  render_success(
@@ -131,26 +138,28 @@ module Dscf
131
138
  end
132
139
 
133
140
  # Creates an Agent record when included in signup request (mobile onboarding)
134
- def create_agent_from_signup!
141
+ def create_agent_from_signup!(user)
135
142
  return unless defined?(Dscf::Marketplace::Agent)
136
143
 
137
144
  Dscf::Marketplace::Agent.create!(
138
145
  name: agent_signup_params[:name],
139
146
  phone: agent_signup_params[:phone],
140
147
  service_area: agent_signup_params[:service_area],
141
- fayda_number: agent_signup_params[:fayda_number]
148
+ fayda_number: agent_signup_params[:fayda_number],
149
+ user: user
142
150
  )
143
151
  end
144
152
 
145
153
  # Creates a Retailer record when included in signup request (mobile onboarding)
146
- def create_retailer_from_signup!
154
+ def create_retailer_from_signup!(user)
147
155
  return unless defined?(Dscf::Marketplace::Retailer)
148
156
 
149
157
  Dscf::Marketplace::Retailer.create!(
150
158
  name: retailer_signup_params[:name],
151
159
  phone: retailer_signup_params[:phone],
152
160
  tin_number: retailer_signup_params[:tin_number],
153
- location: retailer_signup_params[:location]
161
+ location: retailer_signup_params[:location],
162
+ user: user
154
163
  )
155
164
  end
156
165
 
@@ -0,0 +1,42 @@
1
+ module Dscf
2
+ module Core
3
+ class DocumentsController < ApplicationController
4
+ include Common
5
+
6
+ def index
7
+ super do
8
+ business = Business.find(params[:business_id])
9
+ business.documents
10
+ end
11
+ end
12
+
13
+ def create
14
+ super do
15
+ business = Business.find(params[:business_id])
16
+ doc = business.documents.new(document_type: :business_license)
17
+ if params[:document] && params[:document][:file].present?
18
+ doc.files.attach(params[:document][:file])
19
+ end
20
+ doc
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def model_params
27
+ params.require(:document).permit(:document_type, :file)
28
+ end
29
+
30
+ def eager_loaded_associations
31
+ [:files_attachments]
32
+ end
33
+
34
+ def set_object
35
+ business = Business.find(params[:business_id])
36
+ @obj = business.documents.find(params[:id])
37
+ rescue ActiveRecord::RecordNotFound
38
+ render_error("Document not found", status: :not_found)
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,25 @@
1
+ module Dscf
2
+ module Core
3
+ class AddressPolicy < ApplicationPolicy
4
+ def index?
5
+ user.present?
6
+ end
7
+
8
+ def show?
9
+ user.present? && (record.user_id == user.id || record.user_id.nil?)
10
+ end
11
+
12
+ def create?
13
+ user.present?
14
+ end
15
+
16
+ def update?
17
+ user.present? && (record.user_id == user.id || record.user_id.nil?)
18
+ end
19
+
20
+ def destroy?
21
+ user.present? && (record.user_id == user.id || record.user_id.nil?)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -22,7 +22,7 @@ module Dscf
22
22
  end
23
23
 
24
24
  def my_business?
25
- user.has_permission?("businesses.index")
25
+ user.present?
26
26
  end
27
27
  end
28
28
  end
@@ -0,0 +1,25 @@
1
+ module Dscf
2
+ module Core
3
+ class DocumentPolicy < ApplicationPolicy
4
+ def index?
5
+ user.present?
6
+ end
7
+
8
+ def show?
9
+ user.present? && (record.documentable.respond_to?(:user_id) ? record.documentable.user_id == user.id : true)
10
+ end
11
+
12
+ def create?
13
+ user.present?
14
+ end
15
+
16
+ def update?
17
+ user.present? && (record.documentable.respond_to?(:user_id) ? record.documentable.user_id == user.id : true)
18
+ end
19
+
20
+ def destroy?
21
+ user.present? && (record.documentable.respond_to?(:user_id) ? record.documentable.user_id == user.id : true)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -1,7 +1,7 @@
1
1
  module Dscf
2
2
  module Core
3
3
  class DocumentSerializer < ActiveModel::Serializer
4
- attributes :id, :document_type, :file_urls, :is_verified, :verified_at, :created_at, :updated_at
4
+ attributes :id, :document_type, :file_urls, :is_verified, :verified_at, :created_at, :updated_at, :name, :url
5
5
 
6
6
  belongs_to :documentable, polymorphic: true
7
7
  belongs_to :verified_by, polymorphic: true, optional: true
@@ -9,6 +9,14 @@ module Dscf
9
9
  def file_urls
10
10
  object.file_urls
11
11
  end
12
+
13
+ def name
14
+ object.files.attached? ? object.files.first.filename.to_s : object.document_type.to_s.titleize
15
+ end
16
+
17
+ def url
18
+ object.file_urls.first
19
+ end
12
20
  end
13
21
  end
14
22
  end
@@ -1,7 +1,7 @@
1
1
  module Dscf
2
2
  module Core
3
3
  class UserAuthSerializer < ActiveModel::Serializer
4
- attributes :id, :email, :phone, :verified_at, :permissions
4
+ attributes :id, :email, :phone, :verified_at, :permissions, :review_status
5
5
 
6
6
  has_one :user_profile, serializer: Dscf::Core::UserProfileSerializer
7
7
  has_many :roles, serializer: Dscf::Core::RoleLightSerializer
@@ -9,6 +9,29 @@ module Dscf
9
9
  def permissions
10
10
  object.active_permissions.to_a
11
11
  end
12
+
13
+ def review_status
14
+ return @review_status if defined?(@review_status)
15
+
16
+ @review_status = if defined?(Dscf::Marketplace::Agent) && (agent = Dscf::Marketplace::Agent.find_by(user_id: object.id))
17
+ { type: "agent", entity_id: agent.id, status: agent.verification_status }
18
+ elsif defined?(Dscf::Marketplace::Supplier) && (supplier = supplier_for_user)
19
+ { type: "supplier", entity_id: supplier.id, status: supplier.current_status_for(:default) }
20
+ elsif defined?(Dscf::Marketplace::Retailer) && (retailer = Dscf::Marketplace::Retailer.find_by(user_id: object.id))
21
+ { type: "retailer", entity_id: retailer.id, status: "pending" }
22
+ else
23
+ nil
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ def supplier_for_user
30
+ business = Dscf::Core::Business.find_by(user_id: object.id)
31
+ return nil unless business && defined?(Dscf::Marketplace::Supplier)
32
+
33
+ Dscf::Marketplace::Supplier.find_by(business_id: business.id)
34
+ end
12
35
  end
13
36
  end
14
37
  end
@@ -5,9 +5,14 @@ module Dscf
5
5
  class NotificationService
6
6
  class << self
7
7
  def deliver(notification)
8
+ phone = notification.recipient&.phone
9
+ raise ArgumentError, "Recipient phone is blank" if phone.blank?
8
10
  adapter = resolve_adapter
9
- adapter.send_sms(notification.recipient.phone, notification.body)
11
+ adapter.send_sms(phone, notification.body)
10
12
  notification.update!(status: :delivered, delivered_at: Time.current)
13
+ rescue => e
14
+ Rails.logger.error("Notification delivery failed: #{e.message}")
15
+ notification.update(status: :failed) rescue nil
11
16
  end
12
17
 
13
18
  def resolve_adapter
data/config/routes.rb CHANGED
@@ -13,6 +13,7 @@ Dscf::Core::Engine.routes.draw do
13
13
  patch "request_modification"
14
14
  patch "resubmit"
15
15
  end
16
+ resources :documents, only: %i[index create destroy], controller: "documents"
16
17
  end
17
18
 
18
19
  resources :roles do
@@ -1,5 +1,5 @@
1
1
  module Dscf
2
2
  module Core
3
- VERSION = "0.3.6".freeze
3
+ VERSION = "0.3.8".freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dscf-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.6
4
+ version: 0.3.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Asrat
@@ -442,6 +442,7 @@ files:
442
442
  - app/controllers/dscf/core/auth_controller.rb
443
443
  - app/controllers/dscf/core/business_types_controller.rb
444
444
  - app/controllers/dscf/core/businesses_controller.rb
445
+ - app/controllers/dscf/core/documents_controller.rb
445
446
  - app/controllers/dscf/core/fayda_verifications_controller.rb
446
447
  - app/controllers/dscf/core/files_controller.rb
447
448
  - app/controllers/dscf/core/permissions_controller.rb
@@ -475,9 +476,11 @@ files:
475
476
  - app/models/dscf/core/user_profile.rb
476
477
  - app/models/dscf/core/user_role.rb
477
478
  - app/policies/dscf/core/account_management_policy.rb
479
+ - app/policies/dscf/core/address_policy.rb
478
480
  - app/policies/dscf/core/application_policy.rb
479
481
  - app/policies/dscf/core/business_policy.rb
480
482
  - app/policies/dscf/core/business_type_policy.rb
483
+ - app/policies/dscf/core/document_policy.rb
481
484
  - app/policies/dscf/core/permission_policy.rb
482
485
  - app/policies/dscf/core/role_policy.rb
483
486
  - app/serializers/dscf/core/address_serializer.rb