dscf-marketplace 0.13.10 → 0.13.11
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/aggregator_listings_controller.rb +6 -1
- data/app/models/concerns/dscf/marketplace/attachment_urls.rb +29 -0
- data/app/models/dscf/marketplace/agent.rb +4 -6
- data/app/models/dscf/marketplace/aggregator_listing.rb +39 -1
- data/app/models/dscf/marketplace/product.rb +2 -17
- data/app/models/dscf/marketplace/supplier.rb +2 -3
- data/app/serializers/dscf/marketplace/aggregator_listing_serializer.rb +1 -1
- data/lib/dscf/marketplace/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7dd1a186494d212b2e44fe094c3f31440f21764924868264316894e1152a7160
|
|
4
|
+
data.tar.gz: 03f4880b762fcf7ecebd26cc7368b07ee215b8445df4b61173b17a59dabca686
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 25a80f9a800788bb55dcfd6d44bf991b6bcf8ae25a11d4a5aa539b8db3154d0351107a990ca8844096d59a7bb4405979e52e4d8c8a0e1efc132dedbebfe2a412
|
|
7
|
+
data.tar.gz: 8efd86df8d48b449a15921f8acddd728b957e677840180111614d8680fb0c08c723b8533a110d7da13b5e126121eba73a9de5f18ff93ec49fd91864ef92221c5
|
|
@@ -5,7 +5,12 @@ module Dscf
|
|
|
5
5
|
|
|
6
6
|
def feed
|
|
7
7
|
authorize @clazz.new, :index?
|
|
8
|
-
|
|
8
|
+
# Retailer-facing feed: only listings that are truly offerable — own
|
|
9
|
+
# status :active AND (for supplier-sourced) the supplier hasn't paused
|
|
10
|
+
# or run out of stock. A listing whose supplier paused drops out here.
|
|
11
|
+
listings = @clazz.active
|
|
12
|
+
.includes(:product, {supplier_product: :product}, {sub_supplier_product: :product})
|
|
13
|
+
.select(&:available?)
|
|
9
14
|
|
|
10
15
|
options = {
|
|
11
16
|
include: default_serializer_includes[:index] || [],
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Dscf
|
|
2
|
+
module Marketplace
|
|
3
|
+
# Shared Active Storage URL helpers. Produces a host-aware proxy URL that
|
|
4
|
+
# works behind the API's `/api` script_name — unlike `only_path: true`,
|
|
5
|
+
# which drops the script_name and 404s when the client resolves the path.
|
|
6
|
+
module AttachmentUrls
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
|
|
9
|
+
private
|
|
10
|
+
|
|
11
|
+
def attachment_url_for(attachment)
|
|
12
|
+
return unless attachment.present?
|
|
13
|
+
return if attachment.respond_to?(:attached?) && !attachment.attached?
|
|
14
|
+
|
|
15
|
+
Rails.application.routes.url_helpers.rails_storage_proxy_url(attachment, **active_storage_url_options)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def active_storage_url_options
|
|
19
|
+
url_options = Rails.application.config.x.active_storage_url_options.presence ||
|
|
20
|
+
Rails.application.routes.default_url_options.presence ||
|
|
21
|
+
Rails.application.config.action_controller.default_url_options.presence ||
|
|
22
|
+
Rails.application.config.action_mailer.default_url_options.presence ||
|
|
23
|
+
{}
|
|
24
|
+
|
|
25
|
+
url_options.to_h.symbolize_keys.compact
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
module Dscf::Marketplace
|
|
2
2
|
class Agent < ApplicationRecord
|
|
3
|
+
include Dscf::Marketplace::AttachmentUrls
|
|
4
|
+
|
|
3
5
|
# Associations
|
|
4
6
|
belongs_to :user, class_name: "Dscf::Core::User", optional: true
|
|
5
7
|
belongs_to :onboarded_by, class_name: "Dscf::Core::Business", optional: true
|
|
@@ -44,15 +46,11 @@ module Dscf::Marketplace
|
|
|
44
46
|
end
|
|
45
47
|
|
|
46
48
|
def photo_url
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
Rails.application.routes.url_helpers.rails_storage_proxy_url(photo, only_path: true)
|
|
49
|
+
attachment_url_for(photo)
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
def national_id_url
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
Rails.application.routes.url_helpers.rails_storage_proxy_url(national_id, only_path: true)
|
|
53
|
+
attachment_url_for(national_id)
|
|
56
54
|
end
|
|
57
55
|
|
|
58
56
|
private
|
|
@@ -14,6 +14,12 @@ module Dscf::Marketplace
|
|
|
14
14
|
# how the product/cost resolve, and who fulfils an order line placed against it.
|
|
15
15
|
enum :source_kind, {catalog: 0, supplier: 1, sub_supplier: 2}, default: :catalog
|
|
16
16
|
|
|
17
|
+
# At listing time the quantity for supplier/sub_supplier sources is the
|
|
18
|
+
# supplier's own maintained stock — the aggregator never types it in. Seed it
|
|
19
|
+
# from upstream on create; afterwards it's decremented by order fulfilment
|
|
20
|
+
# like any listing, so we don't re-sync on update.
|
|
21
|
+
before_validation :sync_quantity_from_source, on: :create
|
|
22
|
+
|
|
17
23
|
validates :price, numericality: {greater_than: 0}, presence: true
|
|
18
24
|
# Quantity must be positive while the listing is orderable, but a sold-out
|
|
19
25
|
# listing legitimately holds 0 — that's exactly the state set when the last
|
|
@@ -86,12 +92,44 @@ module Dscf::Marketplace
|
|
|
86
92
|
supplier_product&.business if supplier?
|
|
87
93
|
end
|
|
88
94
|
|
|
95
|
+
# Is the upstream source still offering this? For supplier/sub_supplier
|
|
96
|
+
# sources, an aggregator listing must follow the supplier: when the supplier
|
|
97
|
+
# pauses (deactivates their supplier product) or runs out of stock, the
|
|
98
|
+
# listing is no longer offerable even if its own status is still :active.
|
|
99
|
+
# Catalog listings have no upstream — the aggregator fulfils them directly.
|
|
100
|
+
def upstream_active?
|
|
101
|
+
case source_kind
|
|
102
|
+
when "supplier" then supplier_product&.active? && supplier_product.available_quantity.to_i.positive?
|
|
103
|
+
when "sub_supplier" then sub_supplier_product.present?
|
|
104
|
+
else true
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# Status as retailers/aggregator should see it: a listing whose own status is
|
|
109
|
+
# :active but whose supplier has paused reads as :paused (auto-followed),
|
|
110
|
+
# without mutating the stored status.
|
|
111
|
+
def effective_status
|
|
112
|
+
return "paused" if active? && !upstream_active?
|
|
113
|
+
|
|
114
|
+
status
|
|
115
|
+
end
|
|
116
|
+
|
|
89
117
|
def available?
|
|
90
|
-
active? && quantity
|
|
118
|
+
active? && quantity.to_i.positive? && upstream_active?
|
|
91
119
|
end
|
|
92
120
|
|
|
93
121
|
def total_value
|
|
94
122
|
price * quantity
|
|
95
123
|
end
|
|
124
|
+
|
|
125
|
+
private
|
|
126
|
+
|
|
127
|
+
def sync_quantity_from_source
|
|
128
|
+
case source_kind
|
|
129
|
+
when "supplier" then self.quantity = supplier_product&.available_quantity
|
|
130
|
+
when "sub_supplier" then self.quantity = sub_supplier_product&.quantity
|
|
131
|
+
# catalog: aggregator sets its own quantity
|
|
132
|
+
end
|
|
133
|
+
end
|
|
96
134
|
end
|
|
97
135
|
end
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
module Dscf
|
|
2
2
|
module Marketplace
|
|
3
3
|
class Product < ApplicationRecord
|
|
4
|
+
include Dscf::Marketplace::AttachmentUrls
|
|
5
|
+
|
|
4
6
|
belongs_to :category, class_name: "Dscf::Marketplace::Category"
|
|
5
7
|
belongs_to :unit, class_name: "Dscf::Marketplace::Unit"
|
|
6
8
|
|
|
@@ -65,23 +67,6 @@ module Dscf
|
|
|
65
67
|
images.map { |image| attachment_url_for(image) }
|
|
66
68
|
end
|
|
67
69
|
|
|
68
|
-
private
|
|
69
|
-
def attachment_url_for(attachment)
|
|
70
|
-
return unless attachment.present?
|
|
71
|
-
return if attachment.respond_to?(:attached?) && !attachment.attached?
|
|
72
|
-
|
|
73
|
-
Rails.application.routes.url_helpers.rails_storage_proxy_url(attachment, **active_storage_url_options)
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
def active_storage_url_options
|
|
77
|
-
url_options = Rails.application.config.x.active_storage_url_options.presence ||
|
|
78
|
-
Rails.application.routes.default_url_options.presence ||
|
|
79
|
-
Rails.application.config.action_controller.default_url_options.presence ||
|
|
80
|
-
Rails.application.config.action_mailer.default_url_options.presence ||
|
|
81
|
-
{}
|
|
82
|
-
|
|
83
|
-
url_options.to_h.symbolize_keys.compact
|
|
84
|
-
end
|
|
85
70
|
end
|
|
86
71
|
end
|
|
87
72
|
end
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
module Dscf::Marketplace
|
|
2
2
|
class Supplier < ApplicationRecord
|
|
3
3
|
include Dscf::Core::ReviewableModel
|
|
4
|
+
include Dscf::Marketplace::AttachmentUrls
|
|
4
5
|
|
|
5
6
|
belongs_to :business, class_name: "Dscf::Core::Business"
|
|
6
7
|
has_many :supplier_products, class_name: "Dscf::Marketplace::SupplierProduct",
|
|
@@ -92,9 +93,7 @@ module Dscf::Marketplace
|
|
|
92
93
|
def document_urls
|
|
93
94
|
return [] unless documents.attached?
|
|
94
95
|
|
|
95
|
-
documents.map
|
|
96
|
-
Rails.application.routes.url_helpers.rails_storage_proxy_url(doc, only_path: true)
|
|
97
|
-
end
|
|
96
|
+
documents.map { |doc| attachment_url_for(doc) }
|
|
98
97
|
end
|
|
99
98
|
|
|
100
99
|
private
|
|
@@ -3,7 +3,7 @@ module Dscf
|
|
|
3
3
|
class AggregatorListingSerializer < ActiveModel::Serializer
|
|
4
4
|
attributes :id, :aggregator_id, :source_kind, :supplier_product_id, :product_id,
|
|
5
5
|
:sub_supplier_product_id, :price, :quantity, :cost_price, :margin,
|
|
6
|
-
:status, :created_at, :updated_at, :total_value, :available?,
|
|
6
|
+
:status, :effective_status, :created_at, :updated_at, :total_value, :available?,
|
|
7
7
|
:product_name, :product_description, :thumbnail_url, :images_urls,
|
|
8
8
|
:source_label
|
|
9
9
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dscf-marketplace
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.13.
|
|
4
|
+
version: 0.13.11
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Asrat
|
|
@@ -446,6 +446,7 @@ files:
|
|
|
446
446
|
- app/controllers/dscf/marketplace/units_controller.rb
|
|
447
447
|
- app/jobs/dscf/marketplace/application_job.rb
|
|
448
448
|
- app/mailers/dscf/marketplace/application_mailer.rb
|
|
449
|
+
- app/models/concerns/dscf/marketplace/attachment_urls.rb
|
|
449
450
|
- app/models/dscf/marketplace/agent.rb
|
|
450
451
|
- app/models/dscf/marketplace/aggregator_listing.rb
|
|
451
452
|
- app/models/dscf/marketplace/application_record.rb
|