dscf-marketplace 0.8.3 → 0.8.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: 2ba92567e3cf0c48228c8e2e4f163a9125728b4bea281fc043bd82c346921bb2
4
- data.tar.gz: 0b404765e8874d3c2a7b80f5e090c12afc84179b0223fd51e02d39fc91e80970
3
+ metadata.gz: 3ccdf7ab2d80d24d3125fc70cd2967e82b64ceec4fecad26005cc38539416d3d
4
+ data.tar.gz: 513a5ca0fc82efe0e44ed34d4f5ccc9360c6508747ae569bda5c36a8497f00d5
5
5
  SHA512:
6
- metadata.gz: 91d1c4eacb55a8cf3f2c084d4e37f18f48f14d84d5b2e7b35eb2fe59e0d031b5a67fef01e0ccf39f40a0c4a0a174e93246b94016377a3a3ca6cb20410a9a898b
7
- data.tar.gz: 07d58a461e9d548e7a2081ed62c343b72ec084276ef8aac68b38c561d6b7cda47f1501a056c9097b04b80eea40d1c9d72276f298608eb6440c3f156d2bd683e2
6
+ metadata.gz: 6293f513a29b0e11b5300350af009c07504582dd3f29ef423cb3ee14ee87e8389397cad18ab7e7b505ff598f92a9cf06ba99f0e4cd44ee91917928f79e3579e3
7
+ data.tar.gz: 68c91b028dbdce0862f7dafedf85e262469dc36bcdcd943e036edfe0ea3b271a56233870d4075272ae6da618d55c4ba0b2539bf74eff349ec83f339bd814d5ff
@@ -0,0 +1,57 @@
1
+ module Dscf
2
+ module Marketplace
3
+ class AgentsController < ApplicationController
4
+ include Dscf::Core::Common
5
+
6
+ def register
7
+ authorize @clazz.new, :register?
8
+
9
+ obj = @clazz.new(registration_params)
10
+ ActiveRecord::Base.transaction do
11
+ if obj.save
12
+ render_success("agent.success.register", data: obj, status: :created)
13
+ else
14
+ render_error("agent.errors.register", errors: obj.errors.full_messages[0], status: :unprocessable_entity)
15
+ end
16
+ end
17
+ end
18
+
19
+ def destroy
20
+ @obj = find_record
21
+ authorize @obj
22
+ @obj.destroy!
23
+ render_success("agent.success.destroy")
24
+ end
25
+
26
+ private
27
+
28
+ def model_params
29
+ params.require(:agent).permit(
30
+ :name, :phone, :service_area, :fayda_number, :photo, :onboarded_by_id
31
+ )
32
+ end
33
+
34
+ # Registration allows same fields but no authentication required
35
+ def registration_params
36
+ params.require(:agent).permit(
37
+ :name, :phone, :service_area, :fayda_number, :onboarded_by_id
38
+ )
39
+ end
40
+
41
+ def eager_loaded_associations
42
+ [:onboarded_by]
43
+ end
44
+
45
+ def default_serializer_includes
46
+ {
47
+ index: [:onboarded_by],
48
+ show: [:onboarded_by]
49
+ }
50
+ end
51
+
52
+ def find_record
53
+ @clazz.find(params[:id])
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,58 @@
1
+ module Dscf::Marketplace
2
+ class Agent < ApplicationRecord
3
+ # Associations
4
+ belongs_to :onboarded_by, class_name: "Dscf::Core::Business", optional: true
5
+ has_one_attached :photo
6
+
7
+ # Enums
8
+ enum :status, { active: 0, inactive: 1, suspended: 2 }, default: :active
9
+ enum :verification_status, {
10
+ pending: 0,
11
+ verified: 1,
12
+ rejected: 2,
13
+ under_review: 3
14
+ }, default: :pending
15
+
16
+ # Callbacks
17
+ before_validation :generate_agent_code, on: :create
18
+
19
+ # Validations
20
+ validates :code, presence: true, uniqueness: true
21
+ validates :name, presence: true
22
+ validates :service_area, presence: true
23
+ validates :phone, presence: true
24
+
25
+ # Scopes
26
+ scope :active, -> { where(status: :active) }
27
+ scope :inactive, -> { where(status: :inactive) }
28
+ scope :suspended, -> { where(status: :suspended) }
29
+ scope :by_onboarded_by, ->(business_id) { where(onboarded_by_id: business_id) }
30
+ scope :verified, -> { where(verification_status: :verified) }
31
+ scope :pending_verification, -> { where(verification_status: :pending) }
32
+
33
+ # Ransack
34
+ def self.ransackable_attributes(_auth_object = nil)
35
+ %w[id code name phone service_area status fayda_number verification_status
36
+ onboarded_by_id created_at updated_at]
37
+ end
38
+
39
+ def self.ransackable_associations(_auth_object = nil)
40
+ %w[onboarded_by photo_attachment photo_blob]
41
+ end
42
+
43
+ def photo_url
44
+ return nil unless photo.attached?
45
+
46
+ Rails.application.routes.url_helpers.rails_blob_url(photo, only_path: true)
47
+ end
48
+
49
+ private
50
+
51
+ def generate_agent_code
52
+ loop do
53
+ self.code = "AGT-#{SecureRandom.hex(4).upcase}"
54
+ break unless self.class.exists?(code: code)
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,29 @@
1
+ module Dscf
2
+ module Marketplace
3
+ class AgentPolicy < Dscf::Core::ApplicationPolicy
4
+ def index?
5
+ true
6
+ end
7
+
8
+ def show?
9
+ true
10
+ end
11
+
12
+ def create?
13
+ user.present?
14
+ end
15
+
16
+ def update?
17
+ user.present?
18
+ end
19
+
20
+ def destroy?
21
+ user.super_admin?
22
+ end
23
+
24
+ def register?
25
+ true
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,15 @@
1
+ module Dscf
2
+ module Marketplace
3
+ class AgentSerializer < ActiveModel::Serializer
4
+ attributes :id, :code, :name, :phone, :service_area, :status,
5
+ :fayda_number, :verification_status, :onboarded_by_id,
6
+ :photo_url, :created_at, :updated_at
7
+
8
+ belongs_to :onboarded_by, serializer: Dscf::Core::BusinessSerializer
9
+
10
+ def photo_url
11
+ object.photo_url
12
+ end
13
+ end
14
+ end
15
+ end
@@ -401,6 +401,22 @@ en:
401
401
  record_not_found: "Record not found"
402
402
  supplier_not_found: "Supplier not found"
403
403
 
404
+ agent:
405
+ success:
406
+ index: "Agents retrieved successfully"
407
+ show: "Agent details retrieved successfully"
408
+ create: "Agent created successfully"
409
+ update: "Agent updated successfully"
410
+ destroy: "Agent deleted successfully"
411
+ register: "Agent registered successfully"
412
+ errors:
413
+ index: "Failed to retrieve agents"
414
+ show: "Failed to retrieve agent details"
415
+ create: "Failed to create agent"
416
+ update: "Failed to update agent"
417
+ destroy: "Failed to delete agent"
418
+ register: "Failed to register agent"
419
+
404
420
  dashboard:
405
421
  success:
406
422
  summary: "Dashboard summary retrieved successfully"
data/config/routes.rb CHANGED
@@ -149,4 +149,11 @@ Dscf::Marketplace::Engine.routes.draw do
149
149
 
150
150
  # Dashboard
151
151
  get "dashboard/summary", to: "dashboard#summary"
152
+
153
+ # Agent Management
154
+ resources :agents do
155
+ collection do
156
+ post "register"
157
+ end
158
+ end
152
159
  end
@@ -0,0 +1,21 @@
1
+ class CreateDscfMarketplaceAgents < ActiveRecord::Migration[8.1]
2
+ def change
3
+ create_table "dscf_marketplace_agents" do |t|
4
+ t.string "code", null: false
5
+ t.string "name", null: false
6
+ t.string "phone"
7
+ t.text "service_area"
8
+ t.integer "status", default: 0, null: false
9
+ t.string "fayda_number"
10
+ t.integer "verification_status", default: 0, null: false
11
+ t.bigint "onboarded_by_id"
12
+ t.timestamps
13
+ end
14
+
15
+ add_index "dscf_marketplace_agents", "code", unique: true, name: "code_on_dm_agents_indx"
16
+ add_index "dscf_marketplace_agents", "status", name: "status_on_dm_agents_indx"
17
+ add_index "dscf_marketplace_agents", "onboarded_by_id", name: "onboarded_by_on_dm_agents_indx"
18
+
19
+ add_foreign_key "dscf_marketplace_agents", "dscf_core_businesses", column: "onboarded_by_id"
20
+ end
21
+ end
data/db/seeds.rb CHANGED
@@ -21,6 +21,8 @@ Dscf::Core::PermissionRegistry.register("dscf-marketplace") do
21
21
  resource :delivery_order_items, actions: %i[index show create update destroy receiver_confirm report_issue dispute_delivery]
22
22
  resource :delivery_vehicles, actions: %i[index show create update destroy]
23
23
  resource :locations, actions: %i[get_location]
24
+ resource :agents, actions: %i[index show create update destroy register]
25
+ resource :dashboard, actions: %i[summary]
24
26
  end
25
27
 
26
28
  user_role = Dscf::Core::Role.find_or_create_by!(code: "USER") do |role|
@@ -1,5 +1,5 @@
1
1
  module Dscf
2
2
  module Marketplace
3
- VERSION = "0.8.3".freeze
3
+ VERSION = "0.8.4".freeze
4
4
  end
5
5
  end
@@ -0,0 +1,10 @@
1
+ FactoryBot.define do
2
+ factory :dscf_marketplace_agent, class: "Dscf::Marketplace::Agent" do
3
+ code { "AGT-#{SecureRandom.hex(4).upcase}" }
4
+ name { Faker::Name.name }
5
+ phone { Faker::PhoneNumber.phone_number }
6
+ service_area { "Bole" }
7
+ status { :active }
8
+ verification_status { :pending }
9
+ end
10
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dscf-marketplace
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.3
4
+ version: 0.8.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Asrat
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2026-05-28 00:00:00.000000000 Z
10
+ date: 2026-05-29 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: rails
@@ -417,6 +417,7 @@ files:
417
417
  - MIT-LICENSE
418
418
  - Rakefile
419
419
  - app/controllers/concerns/dscf/marketplace/demo_permission_bypass.rb
420
+ - app/controllers/dscf/marketplace/agents_controller.rb
420
421
  - app/controllers/dscf/marketplace/aggregator_listings_controller.rb
421
422
  - app/controllers/dscf/marketplace/application_controller.rb
422
423
  - app/controllers/dscf/marketplace/categories_controller.rb
@@ -440,6 +441,7 @@ files:
440
441
  - app/controllers/dscf/marketplace/units_controller.rb
441
442
  - app/jobs/dscf/marketplace/application_job.rb
442
443
  - app/mailers/dscf/marketplace/application_mailer.rb
444
+ - app/models/dscf/marketplace/agent.rb
443
445
  - app/models/dscf/marketplace/aggregator_listing.rb
444
446
  - app/models/dscf/marketplace/application_record.rb
445
447
  - app/models/dscf/marketplace/category.rb
@@ -460,6 +462,7 @@ files:
460
462
  - app/models/dscf/marketplace/supplier_product.rb
461
463
  - app/models/dscf/marketplace/unit.rb
462
464
  - app/models/dscf/marketplace/unit_conversion.rb
465
+ - app/policies/dscf/marketplace/agent_policy.rb
463
466
  - app/policies/dscf/marketplace/aggregator_listing_policy.rb
464
467
  - app/policies/dscf/marketplace/category_policy.rb
465
468
  - app/policies/dscf/marketplace/dashboard_policy.rb
@@ -480,6 +483,7 @@ files:
480
483
  - app/policies/dscf/marketplace/supplier_product_policy.rb
481
484
  - app/policies/dscf/marketplace/unit_conversion_policy.rb
482
485
  - app/policies/dscf/marketplace/unit_policy.rb
486
+ - app/serializers/dscf/marketplace/agent_serializer.rb
483
487
  - app/serializers/dscf/marketplace/aggregator_listing_serializer.rb
484
488
  - app/serializers/dscf/marketplace/category_serializer.rb
485
489
  - app/serializers/dscf/marketplace/delivery_order_item_serializer.rb
@@ -553,6 +557,7 @@ files:
553
557
  - db/migrate/20260514000005_create_dscf_marketplace_aggregator_listings.rb
554
558
  - db/migrate/20260514000006_add_supplier_id_to_addresses.rb
555
559
  - db/migrate/20260527000001_add_orchestrator_fields_to_listings.rb
560
+ - db/migrate/20260529000001_create_dscf_marketplace_agents.rb
556
561
  - db/seeds.rb
557
562
  - lib/dscf/marketplace.rb
558
563
  - lib/dscf/marketplace/engine.rb
@@ -564,6 +569,7 @@ files:
564
569
  - spec/factories/dscf/core/roles.rb
565
570
  - spec/factories/dscf/core/user_roles.rb
566
571
  - spec/factories/dscf/core/users.rb
572
+ - spec/factories/dscf/marketplace/agents.rb
567
573
  - spec/factories/dscf/marketplace/aggregator_listings.rb
568
574
  - spec/factories/dscf/marketplace/categories.rb
569
575
  - spec/factories/dscf/marketplace/delivery_order_items.rb