dscf-marketplace 0.8.2 → 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: bc4f1d1a9a6e410b60d37864c916ba34f69783495d87582d109e33c858d9b872
4
- data.tar.gz: d4633eb9e5d1efb5adefaa1d74837b542aa17cebb6196d532baf7b3e7278bd03
3
+ metadata.gz: 3ccdf7ab2d80d24d3125fc70cd2967e82b64ceec4fecad26005cc38539416d3d
4
+ data.tar.gz: 513a5ca0fc82efe0e44ed34d4f5ccc9360c6508747ae569bda5c36a8497f00d5
5
5
  SHA512:
6
- metadata.gz: 19e8ec54666855599c42a59a5946d343cdc7fd75d9e464a484f3495dea4109dbd25a5e705fe32916901f323ec98f5f46188c629191fbdf0e7091029ed3b87293
7
- data.tar.gz: 1e5b40b3498eaacddd0d3fce068f8997ed04e5c38d531a244249027424b72c7fe0f6e30e9bb098ddd093cd659a5719eb4066cd16bee76bd92824cbf28d8749a4
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,22 @@
1
+ module Dscf
2
+ module Marketplace
3
+ class DashboardController < ApplicationController
4
+ def summary
5
+ authorize :dashboard, :summary?
6
+
7
+ render_success(
8
+ "dashboard.success.summary",
9
+ data: {
10
+ total_listings: Dscf::Marketplace::Listing.count,
11
+ total_suppliers: Dscf::Marketplace::Supplier.count,
12
+ total_businesses: Dscf::Core::Business.count,
13
+ total_products: Dscf::Marketplace::Product.count,
14
+ pending_supplier_products: Dscf::Marketplace::SupplierProduct.inactive.count,
15
+ active_listings: Dscf::Marketplace::Listing.active.count,
16
+ promoted_listings: Dscf::Marketplace::Listing.orchestrator_promoted.count
17
+ }
18
+ )
19
+ end
20
+ end
21
+ end
22
+ 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,9 @@
1
+ module Dscf
2
+ module Marketplace
3
+ class DashboardPolicy < Dscf::Core::ApplicationPolicy
4
+ def summary?
5
+ user.present?
6
+ end
7
+ end
8
+ end
9
+ 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
@@ -400,7 +400,30 @@ en:
400
400
  operation_failed: "Operation failed"
401
401
  record_not_found: "Record not found"
402
402
  supplier_not_found: "Supplier not found"
403
- activerecord:
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
+
420
+ dashboard:
421
+ success:
422
+ summary: "Dashboard summary retrieved successfully"
423
+ errors:
424
+ summary: "Failed to retrieve dashboard summary"
425
+
426
+ activerecord:
404
427
  errors:
405
428
  messages:
406
429
  record_invalid: "Validation failed: %{errors}"
data/config/routes.rb CHANGED
@@ -146,4 +146,14 @@ Dscf::Marketplace::Engine.routes.draw do
146
146
  resources :delivery_vehicles
147
147
 
148
148
  get "get_location", to: "locations#get_location"
149
+
150
+ # Dashboard
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
149
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.2".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.2
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,9 +417,11 @@ 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
424
+ - app/controllers/dscf/marketplace/dashboard_controller.rb
423
425
  - app/controllers/dscf/marketplace/delivery_order_items_controller.rb
424
426
  - app/controllers/dscf/marketplace/delivery_orders_controller.rb
425
427
  - app/controllers/dscf/marketplace/delivery_stops_controller.rb
@@ -439,6 +441,7 @@ files:
439
441
  - app/controllers/dscf/marketplace/units_controller.rb
440
442
  - app/jobs/dscf/marketplace/application_job.rb
441
443
  - app/mailers/dscf/marketplace/application_mailer.rb
444
+ - app/models/dscf/marketplace/agent.rb
442
445
  - app/models/dscf/marketplace/aggregator_listing.rb
443
446
  - app/models/dscf/marketplace/application_record.rb
444
447
  - app/models/dscf/marketplace/category.rb
@@ -459,8 +462,10 @@ files:
459
462
  - app/models/dscf/marketplace/supplier_product.rb
460
463
  - app/models/dscf/marketplace/unit.rb
461
464
  - app/models/dscf/marketplace/unit_conversion.rb
465
+ - app/policies/dscf/marketplace/agent_policy.rb
462
466
  - app/policies/dscf/marketplace/aggregator_listing_policy.rb
463
467
  - app/policies/dscf/marketplace/category_policy.rb
468
+ - app/policies/dscf/marketplace/dashboard_policy.rb
464
469
  - app/policies/dscf/marketplace/delivery_order_item_policy.rb
465
470
  - app/policies/dscf/marketplace/delivery_order_policy.rb
466
471
  - app/policies/dscf/marketplace/delivery_stop_policy.rb
@@ -478,6 +483,7 @@ files:
478
483
  - app/policies/dscf/marketplace/supplier_product_policy.rb
479
484
  - app/policies/dscf/marketplace/unit_conversion_policy.rb
480
485
  - app/policies/dscf/marketplace/unit_policy.rb
486
+ - app/serializers/dscf/marketplace/agent_serializer.rb
481
487
  - app/serializers/dscf/marketplace/aggregator_listing_serializer.rb
482
488
  - app/serializers/dscf/marketplace/category_serializer.rb
483
489
  - app/serializers/dscf/marketplace/delivery_order_item_serializer.rb
@@ -551,6 +557,7 @@ files:
551
557
  - db/migrate/20260514000005_create_dscf_marketplace_aggregator_listings.rb
552
558
  - db/migrate/20260514000006_add_supplier_id_to_addresses.rb
553
559
  - db/migrate/20260527000001_add_orchestrator_fields_to_listings.rb
560
+ - db/migrate/20260529000001_create_dscf_marketplace_agents.rb
554
561
  - db/seeds.rb
555
562
  - lib/dscf/marketplace.rb
556
563
  - lib/dscf/marketplace/engine.rb
@@ -562,6 +569,7 @@ files:
562
569
  - spec/factories/dscf/core/roles.rb
563
570
  - spec/factories/dscf/core/user_roles.rb
564
571
  - spec/factories/dscf/core/users.rb
572
+ - spec/factories/dscf/marketplace/agents.rb
565
573
  - spec/factories/dscf/marketplace/aggregator_listings.rb
566
574
  - spec/factories/dscf/marketplace/categories.rb
567
575
  - spec/factories/dscf/marketplace/delivery_order_items.rb