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 +4 -4
- data/app/controllers/dscf/marketplace/agents_controller.rb +57 -0
- data/app/controllers/dscf/marketplace/dashboard_controller.rb +22 -0
- data/app/models/dscf/marketplace/agent.rb +58 -0
- data/app/policies/dscf/marketplace/agent_policy.rb +29 -0
- data/app/policies/dscf/marketplace/dashboard_policy.rb +9 -0
- data/app/serializers/dscf/marketplace/agent_serializer.rb +15 -0
- data/config/locales/en.yml +24 -1
- data/config/routes.rb +10 -0
- data/db/migrate/20260529000001_create_dscf_marketplace_agents.rb +21 -0
- data/db/seeds.rb +2 -0
- data/lib/dscf/marketplace/version.rb +1 -1
- data/spec/factories/dscf/marketplace/agents.rb +10 -0
- metadata +10 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3ccdf7ab2d80d24d3125fc70cd2967e82b64ceec4fecad26005cc38539416d3d
|
|
4
|
+
data.tar.gz: 513a5ca0fc82efe0e44ed34d4f5ccc9360c6508747ae569bda5c36a8497f00d5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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,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
|
data/config/locales/en.yml
CHANGED
|
@@ -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
|
-
|
|
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|
|
|
@@ -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.
|
|
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-
|
|
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
|