dscf-marketplace 0.9.8 → 0.10.0
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 +4 -3
- data/app/controllers/dscf/marketplace/orders_controller.rb +6 -1
- data/app/controllers/dscf/marketplace/sub_supplier_products_controller.rb +29 -0
- data/app/models/dscf/marketplace/aggregator_listing.rb +47 -5
- data/app/models/dscf/marketplace/order_item.rb +10 -5
- data/app/serializers/dscf/marketplace/aggregator_listing_serializer.rb +4 -2
- data/app/serializers/dscf/marketplace/order_item_serializer.rb +2 -0
- data/app/serializers/dscf/marketplace/sub_supplier_product_serializer.rb +34 -0
- data/app/services/dscf/marketplace/order_validation_service.rb +10 -1
- data/config/routes.rb +1 -0
- data/db/migrate/20260702000001_unify_aggregator_listing_source.rb +58 -0
- data/lib/dscf/marketplace/engine.rb +3 -0
- data/lib/dscf/marketplace/version.rb +1 -1
- data/spec/factories/dscf/marketplace/aggregator_listings.rb +16 -1
- metadata +5 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 007d71d7d41ca79db79fe7097cda7d169eb5ad0cc973523a8aa6d8ce52555bee
|
|
4
|
+
data.tar.gz: 7b57bd0640a1dc86b8d67e89a4fd93699d1386aab09202266c6bd93ea98de3a8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1a52333ddfbb43afed4d019777f07aabbb2b5bd9fbbdfee5e386075f9e3bc3baa6778d8924ffd7db8c90cf781aa9a4f92418e69610be388ec2d9b3056507a501
|
|
7
|
+
data.tar.gz: f2fd36c7e8073ebbac241432c22639df6b84528f3893045eb686bd6cc4fda94cd145368cb95f548734cab064219323696b2921d1fb6c23a2b7a1346c19bcf5f8
|
|
@@ -5,7 +5,7 @@ module Dscf
|
|
|
5
5
|
|
|
6
6
|
def feed
|
|
7
7
|
authorize @clazz.new, :index?
|
|
8
|
-
listings = @clazz.active.includes(supplier_product: :product)
|
|
8
|
+
listings = @clazz.active.includes(:product, {supplier_product: :product}, {sub_supplier_product: :product})
|
|
9
9
|
|
|
10
10
|
options = {
|
|
11
11
|
include: default_serializer_includes[:index] || [],
|
|
@@ -18,7 +18,7 @@ module Dscf
|
|
|
18
18
|
def my_listings
|
|
19
19
|
authorize @clazz.new, :my_listings?
|
|
20
20
|
businesses = current_user.businesses.pluck(:id)
|
|
21
|
-
listings = @clazz.where(aggregator_id: businesses).includes(supplier_product: :product)
|
|
21
|
+
listings = @clazz.where(aggregator_id: businesses).includes(:product, {supplier_product: :product}, {sub_supplier_product: :product})
|
|
22
22
|
|
|
23
23
|
options = {
|
|
24
24
|
include: default_serializer_includes[:index] || [],
|
|
@@ -32,7 +32,8 @@ module Dscf
|
|
|
32
32
|
|
|
33
33
|
def model_params
|
|
34
34
|
params.require(:aggregator_listing).permit(
|
|
35
|
-
:aggregator_id, :
|
|
35
|
+
:aggregator_id, :source_kind, :supplier_product_id, :product_id,
|
|
36
|
+
:sub_supplier_product_id, :price, :quantity, :status
|
|
36
37
|
)
|
|
37
38
|
end
|
|
38
39
|
end
|
|
@@ -314,7 +314,12 @@ module Dscf
|
|
|
314
314
|
order.status = :pending
|
|
315
315
|
order.ordered_to = aggregator_listing.aggregator
|
|
316
316
|
|
|
317
|
-
product = aggregator_listing.
|
|
317
|
+
product = aggregator_listing.product
|
|
318
|
+
# Order lines from the aggregator feed are auto-sourced to the originating
|
|
319
|
+
# AggregatorListing (regardless of source_kind) — the aggregator already
|
|
320
|
+
# knows the source, so there's no manual pick at split time. The listing's
|
|
321
|
+
# source_kind carries who ultimately fulfils it (self / sub-supplier /
|
|
322
|
+
# supplier), surfaced via source_name for display and confirmation routing.
|
|
318
323
|
order.order_items.build(
|
|
319
324
|
source: aggregator_listing,
|
|
320
325
|
product: product,
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Dscf
|
|
2
|
+
module Marketplace
|
|
3
|
+
class SubSupplierProductsController < ApplicationController
|
|
4
|
+
include Dscf::Core::Common
|
|
5
|
+
|
|
6
|
+
private
|
|
7
|
+
|
|
8
|
+
def model_params
|
|
9
|
+
params.require(:sub_supplier_product).permit(
|
|
10
|
+
:sub_supplier_id, :product_id, :sub_supplier_price,
|
|
11
|
+
:aggregator_price, :quantity, :listed
|
|
12
|
+
)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def eager_loaded_associations
|
|
16
|
+
[ :sub_supplier, :product ]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def default_serializer_includes
|
|
20
|
+
{
|
|
21
|
+
index: [ :sub_supplier, :product ],
|
|
22
|
+
show: [ :sub_supplier, :product ],
|
|
23
|
+
create: [ :sub_supplier, :product ],
|
|
24
|
+
update: [ :sub_supplier, :product ]
|
|
25
|
+
}
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -1,32 +1,74 @@
|
|
|
1
1
|
module Dscf::Marketplace
|
|
2
2
|
class AggregatorListing < ApplicationRecord
|
|
3
3
|
belongs_to :aggregator, class_name: "Dscf::Core::Business"
|
|
4
|
-
belongs_to :supplier_product, class_name: "Dscf::Marketplace::SupplierProduct"
|
|
4
|
+
belongs_to :supplier_product, class_name: "Dscf::Marketplace::SupplierProduct", optional: true
|
|
5
|
+
belongs_to :product, class_name: "Dscf::Marketplace::Product", optional: true
|
|
6
|
+
belongs_to :sub_supplier_product, class_name: "Dscf::Marketplace::SubSupplierProduct", optional: true
|
|
5
7
|
|
|
6
8
|
has_many :order_items, class_name: "Dscf::Marketplace::OrderItem", as: :source, dependent: :nullify
|
|
7
9
|
|
|
8
10
|
delegate :name, :description, :thumbnail_url, :images_urls, to: :product, allow_nil: true
|
|
9
11
|
|
|
10
12
|
enum :status, {active: 0, draft: 1, paused: 2, sold_out: 3}, default: :draft
|
|
13
|
+
# How the aggregator sourced this listing. Drives which reference is required,
|
|
14
|
+
# how the product/cost resolve, and who fulfils an order line placed against it.
|
|
15
|
+
enum :source_kind, {catalog: 0, supplier: 1, sub_supplier: 2}, default: :catalog
|
|
11
16
|
|
|
12
17
|
validates :price, numericality: {greater_than: 0}, presence: true
|
|
13
18
|
validates :quantity, numericality: {greater_than: 0}, presence: true
|
|
14
19
|
validates :aggregator, presence: true
|
|
15
|
-
|
|
20
|
+
|
|
21
|
+
# Each kind requires (and is unique on) exactly one reference.
|
|
22
|
+
validates :supplier_product_id, presence: true, uniqueness: {scope: :aggregator_id}, if: :supplier?
|
|
23
|
+
validates :product_id, presence: true, uniqueness: {scope: :aggregator_id}, if: :catalog?
|
|
24
|
+
validates :sub_supplier_product_id, presence: true, uniqueness: {scope: :aggregator_id}, if: :sub_supplier?
|
|
16
25
|
|
|
17
26
|
scope :active, -> { where(status: :active) }
|
|
18
27
|
scope :by_aggregator, ->(aggregator_id) { where(aggregator_id: aggregator_id) }
|
|
19
28
|
|
|
20
29
|
def self.ransackable_attributes(_auth_object = nil)
|
|
21
|
-
%w[id aggregator_id supplier_product_id price quantity status created_at updated_at]
|
|
30
|
+
%w[id aggregator_id supplier_product_id product_id sub_supplier_product_id source_kind price quantity status created_at updated_at]
|
|
22
31
|
end
|
|
23
32
|
|
|
24
33
|
def self.ransackable_associations(_auth_object = nil)
|
|
25
|
-
%w[aggregator supplier_product]
|
|
34
|
+
%w[aggregator supplier_product product sub_supplier_product]
|
|
26
35
|
end
|
|
27
36
|
|
|
37
|
+
# Resolves the catalogue product regardless of how the listing was sourced.
|
|
28
38
|
def product
|
|
29
|
-
|
|
39
|
+
case source_kind
|
|
40
|
+
when "supplier" then supplier_product&.product
|
|
41
|
+
when "sub_supplier" then sub_supplier_product&.product
|
|
42
|
+
else super
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# The aggregator's cost basis for this listing (nil for catalog — the aggregator
|
|
47
|
+
# sets a selling price directly with no upstream cost to compare against).
|
|
48
|
+
def cost_price
|
|
49
|
+
case source_kind
|
|
50
|
+
when "supplier" then supplier_product&.supplier_price
|
|
51
|
+
when "sub_supplier" then sub_supplier_product&.sub_supplier_price
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def margin
|
|
56
|
+
return nil unless cost_price
|
|
57
|
+
price - cost_price
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Human-readable name of who ultimately fulfils a line placed against this
|
|
61
|
+
# listing. An order line is auto-sourced to the AggregatorListing itself, so
|
|
62
|
+
# this drives the "Product source name" the requirements ask for:
|
|
63
|
+
# catalog -> the aggregator (self-fulfilled)
|
|
64
|
+
# supplier -> the supplier's business name
|
|
65
|
+
# sub_supplier -> the sub-supplier's business name
|
|
66
|
+
def source_label
|
|
67
|
+
case source_kind
|
|
68
|
+
when "supplier" then supplier_product&.business&.name
|
|
69
|
+
when "sub_supplier" then sub_supplier_product&.sub_supplier&.business_name
|
|
70
|
+
else aggregator&.name
|
|
71
|
+
end
|
|
30
72
|
end
|
|
31
73
|
|
|
32
74
|
def available?
|
|
@@ -22,7 +22,7 @@ module Dscf::Marketplace
|
|
|
22
22
|
validates :status, presence: true
|
|
23
23
|
validates :product, presence: true
|
|
24
24
|
validates :unit, presence: true
|
|
25
|
-
validate :
|
|
25
|
+
validate :orderable_source_present
|
|
26
26
|
|
|
27
27
|
# Ransack configuration for secure filtering
|
|
28
28
|
def self.ransackable_attributes(_auth_object = nil)
|
|
@@ -55,10 +55,15 @@ module Dscf::Marketplace
|
|
|
55
55
|
|
|
56
56
|
private
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
58
|
+
# A line must trace back to something orderable: an RFQ quotation item, a
|
|
59
|
+
# supplier listing, or any assigned polymorphic source (aggregator listing,
|
|
60
|
+
# sub-supplier, other supplier/business). The last case is what lets the
|
|
61
|
+
# aggregator reassign a line to another source during splitting.
|
|
62
|
+
def orderable_source_present
|
|
63
|
+
return if quotation_item.present? || listing.present?
|
|
64
|
+
return if source_type.present? && source_id.present?
|
|
65
|
+
|
|
66
|
+
errors.add(:base, "Either a quotation item, a listing, or an assigned source must be present")
|
|
62
67
|
end
|
|
63
68
|
end
|
|
64
69
|
end
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
module Dscf
|
|
2
2
|
module Marketplace
|
|
3
3
|
class AggregatorListingSerializer < ActiveModel::Serializer
|
|
4
|
-
attributes :id, :aggregator_id, :
|
|
4
|
+
attributes :id, :aggregator_id, :source_kind, :supplier_product_id, :product_id,
|
|
5
|
+
:sub_supplier_product_id, :price, :quantity, :cost_price, :margin,
|
|
5
6
|
:status, :created_at, :updated_at, :total_value, :available?,
|
|
6
|
-
:product_name, :product_description, :thumbnail_url, :images_urls
|
|
7
|
+
:product_name, :product_description, :thumbnail_url, :images_urls,
|
|
8
|
+
:source_label
|
|
7
9
|
|
|
8
10
|
belongs_to :aggregator
|
|
9
11
|
|
|
@@ -16,6 +16,8 @@ module Dscf
|
|
|
16
16
|
def source_name
|
|
17
17
|
return nil unless object.source
|
|
18
18
|
case object.source_type
|
|
19
|
+
when 'Dscf::Marketplace::AggregatorListing'
|
|
20
|
+
object.source.try(:source_label)
|
|
19
21
|
when 'Dscf::Marketplace::SubSupplier'
|
|
20
22
|
object.source.try(:business_name) || object.source.try(:name)
|
|
21
23
|
when 'Dscf::Marketplace::Supplier'
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
module Dscf
|
|
2
|
+
module Marketplace
|
|
3
|
+
class SubSupplierProductSerializer < ActiveModel::Serializer
|
|
4
|
+
attributes :id, :sub_supplier_id, :product_id,
|
|
5
|
+
:sub_supplier_price, :aggregator_price, :quantity, :listed,
|
|
6
|
+
:created_at, :updated_at,
|
|
7
|
+
:product_name, :product_sku, :thumbnail_url, :images_urls,
|
|
8
|
+
:sub_supplier_name
|
|
9
|
+
|
|
10
|
+
belongs_to :sub_supplier
|
|
11
|
+
belongs_to :product
|
|
12
|
+
|
|
13
|
+
def product_name
|
|
14
|
+
object.product&.name
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def product_sku
|
|
18
|
+
object.product&.sku
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def thumbnail_url
|
|
22
|
+
object.product&.thumbnail_url
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def images_urls
|
|
26
|
+
object.product&.images_urls
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def sub_supplier_name
|
|
30
|
+
object.sub_supplier&.business_name
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -51,8 +51,17 @@ module Dscf
|
|
|
51
51
|
item
|
|
52
52
|
end
|
|
53
53
|
|
|
54
|
+
# Returns the current price/quantity reference for an item. This is duck-typed:
|
|
55
|
+
# any object responding to #price and #quantity works (Listing or
|
|
56
|
+
# AggregatorListing), since validate_item only reads those two fields.
|
|
54
57
|
private_class_method def self.find_current_active_listing(item)
|
|
55
|
-
#
|
|
58
|
+
# Lines placed from the aggregator feed are sourced to their AggregatorListing —
|
|
59
|
+
# validate against that listing's live price/quantity, not a supplier listing.
|
|
60
|
+
if item.source.is_a?(AggregatorListing)
|
|
61
|
+
return AggregatorListing.active.find_by(id: item.source_id)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Prefer the original supplier listing if still active
|
|
56
65
|
if item.listing && Listing.active.exists?(id: item.listing.id)
|
|
57
66
|
return item.listing
|
|
58
67
|
end
|
data/config/routes.rb
CHANGED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
class UnifyAggregatorListingSource < ActiveRecord::Migration[8.0]
|
|
2
|
+
def up
|
|
3
|
+
# New polymorphic-style source discriminator.
|
|
4
|
+
# 0 = catalog (aggregator lists a master-catalogue product directly)
|
|
5
|
+
# 1 = supplier (aggregator resells a supplier_product) <- the only kind that existed before
|
|
6
|
+
# 2 = sub_supplier (aggregator lists a sub-supplier product)
|
|
7
|
+
add_column :dscf_marketplace_aggregator_listings, :source_kind, :integer, default: 0, null: false
|
|
8
|
+
|
|
9
|
+
# Catalog / sub-supplier sourced listings don't have a supplier_product.
|
|
10
|
+
change_column_null :dscf_marketplace_aggregator_listings, :supplier_product_id, true
|
|
11
|
+
|
|
12
|
+
add_column :dscf_marketplace_aggregator_listings, :product_id, :bigint
|
|
13
|
+
add_column :dscf_marketplace_aggregator_listings, :sub_supplier_product_id, :bigint
|
|
14
|
+
|
|
15
|
+
add_index :dscf_marketplace_aggregator_listings, :product_id, name: "product_on_dm_al_indx"
|
|
16
|
+
add_index :dscf_marketplace_aggregator_listings, :sub_supplier_product_id, name: "ssp_on_dm_al_indx"
|
|
17
|
+
|
|
18
|
+
# Existing rows are all supplier-sourced; backfill kind + denormalised product_id.
|
|
19
|
+
execute(<<~SQL.squish)
|
|
20
|
+
UPDATE dscf_marketplace_aggregator_listings al
|
|
21
|
+
SET source_kind = 1,
|
|
22
|
+
product_id = sp.product_id
|
|
23
|
+
FROM dscf_marketplace_supplier_products sp
|
|
24
|
+
WHERE al.supplier_product_id = sp.id
|
|
25
|
+
AND al.supplier_product_id IS NOT NULL
|
|
26
|
+
SQL
|
|
27
|
+
|
|
28
|
+
# The old unique index assumed supplier_product_id is always present. Replace it
|
|
29
|
+
# with one partial unique index per kind so an aggregator can't double-list the
|
|
30
|
+
# same catalogue product / supplier_product / sub_supplier_product.
|
|
31
|
+
remove_index :dscf_marketplace_aggregator_listings, name: "unique_aggregator_sp_indx"
|
|
32
|
+
|
|
33
|
+
add_index :dscf_marketplace_aggregator_listings, [:aggregator_id, :supplier_product_id],
|
|
34
|
+
unique: true, where: "source_kind = 1", name: "uniq_agg_supplier_product_indx"
|
|
35
|
+
add_index :dscf_marketplace_aggregator_listings, [:aggregator_id, :product_id],
|
|
36
|
+
unique: true, where: "source_kind = 0", name: "uniq_agg_catalog_product_indx"
|
|
37
|
+
add_index :dscf_marketplace_aggregator_listings, [:aggregator_id, :sub_supplier_product_id],
|
|
38
|
+
unique: true, where: "source_kind = 2", name: "uniq_agg_sub_supplier_product_indx"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def down
|
|
42
|
+
remove_index :dscf_marketplace_aggregator_listings, name: "uniq_agg_supplier_product_indx"
|
|
43
|
+
remove_index :dscf_marketplace_aggregator_listings, name: "uniq_agg_catalog_product_indx"
|
|
44
|
+
remove_index :dscf_marketplace_aggregator_listings, name: "uniq_agg_sub_supplier_product_indx"
|
|
45
|
+
|
|
46
|
+
remove_index :dscf_marketplace_aggregator_listings, name: "product_on_dm_al_indx"
|
|
47
|
+
remove_index :dscf_marketplace_aggregator_listings, name: "ssp_on_dm_al_indx"
|
|
48
|
+
|
|
49
|
+
remove_column :dscf_marketplace_aggregator_listings, :product_id
|
|
50
|
+
remove_column :dscf_marketplace_aggregator_listings, :sub_supplier_product_id
|
|
51
|
+
remove_column :dscf_marketplace_aggregator_listings, :source_kind
|
|
52
|
+
|
|
53
|
+
# Restore the original unique index. Rows must be supplier-sourced for this to hold.
|
|
54
|
+
change_column_null :dscf_marketplace_aggregator_listings, :supplier_product_id, false
|
|
55
|
+
add_index :dscf_marketplace_aggregator_listings, [:aggregator_id, :supplier_product_id],
|
|
56
|
+
unique: true, name: "unique_aggregator_sp_indx"
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -28,6 +28,9 @@ module Dscf
|
|
|
28
28
|
resource :units, actions: %i[index show create update destroy]
|
|
29
29
|
resource :unit_conversions, actions: %i[index show create update destroy]
|
|
30
30
|
resource :supplier_products, actions: %i[index show create update destroy my_products]
|
|
31
|
+
resource :sub_suppliers, actions: %i[index show create update destroy]
|
|
32
|
+
resource :sub_supplier_products, actions: %i[index show create update destroy]
|
|
33
|
+
resource :aggregator_listings, actions: %i[index show create update destroy feed my_listings]
|
|
31
34
|
resource :listings, actions: %i[index show create update destroy activate pause sold_out my_listings listings_by_supplier]
|
|
32
35
|
resource :request_for_quotations, actions: %i[index show create update destroy send_rfq close respond my_rfqs filter]
|
|
33
36
|
resource :rfq_items, actions: %i[index show create update destroy]
|
|
@@ -1,9 +1,24 @@
|
|
|
1
1
|
FactoryBot.define do
|
|
2
2
|
factory :dscf_marketplace_aggregator_listing, class: "Dscf::Marketplace::AggregatorListing" do
|
|
3
3
|
association :aggregator, factory: :dscf_core_business
|
|
4
|
-
association :supplier_product, factory: :dscf_marketplace_supplier_product
|
|
5
4
|
price { 250.00 }
|
|
6
5
|
quantity { 50.0 }
|
|
7
6
|
status { :active }
|
|
7
|
+
|
|
8
|
+
# Default: supplier-sourced (resells a supplier_product), matching pre-existing data.
|
|
9
|
+
source_kind { :supplier }
|
|
10
|
+
association :supplier_product, factory: :dscf_marketplace_supplier_product
|
|
11
|
+
|
|
12
|
+
trait :catalog do
|
|
13
|
+
source_kind { :catalog }
|
|
14
|
+
supplier_product { nil }
|
|
15
|
+
association :product, factory: :dscf_marketplace_product
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
trait :sub_supplier do
|
|
19
|
+
source_kind { :sub_supplier }
|
|
20
|
+
supplier_product { nil }
|
|
21
|
+
association :sub_supplier_product, factory: :dscf_marketplace_sub_supplier_product
|
|
22
|
+
end
|
|
8
23
|
end
|
|
9
24
|
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.
|
|
4
|
+
version: 0.10.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Asrat
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-
|
|
10
|
+
date: 2026-07-03 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: rails
|
|
@@ -438,6 +438,7 @@ files:
|
|
|
438
438
|
- app/controllers/dscf/marketplace/request_for_quotations_controller.rb
|
|
439
439
|
- app/controllers/dscf/marketplace/retailers_controller.rb
|
|
440
440
|
- app/controllers/dscf/marketplace/rfq_items_controller.rb
|
|
441
|
+
- app/controllers/dscf/marketplace/sub_supplier_products_controller.rb
|
|
441
442
|
- app/controllers/dscf/marketplace/sub_suppliers_controller.rb
|
|
442
443
|
- app/controllers/dscf/marketplace/supplier_products_controller.rb
|
|
443
444
|
- app/controllers/dscf/marketplace/suppliers_controller.rb
|
|
@@ -514,6 +515,7 @@ files:
|
|
|
514
515
|
- app/serializers/dscf/marketplace/request_for_quotation_serializer.rb
|
|
515
516
|
- app/serializers/dscf/marketplace/retailer_serializer.rb
|
|
516
517
|
- app/serializers/dscf/marketplace/rfq_item_serializer.rb
|
|
518
|
+
- app/serializers/dscf/marketplace/sub_supplier_product_serializer.rb
|
|
517
519
|
- app/serializers/dscf/marketplace/sub_supplier_serializer.rb
|
|
518
520
|
- app/serializers/dscf/marketplace/supplier_product_serializer.rb
|
|
519
521
|
- app/serializers/dscf/marketplace/supplier_serializer.rb
|
|
@@ -590,6 +592,7 @@ files:
|
|
|
590
592
|
- db/migrate/20260619210001_add_user_id_to_dscf_marketplace_agents.rb
|
|
591
593
|
- db/migrate/20260619210002_add_user_id_to_dscf_marketplace_retailers.rb
|
|
592
594
|
- db/migrate/20260622000001_add_validation_and_source_fields_to_dscf_marketplace_order_items.rb
|
|
595
|
+
- db/migrate/20260702000001_unify_aggregator_listing_source.rb
|
|
593
596
|
- db/seeds.rb
|
|
594
597
|
- lib/dscf/marketplace.rb
|
|
595
598
|
- lib/dscf/marketplace/engine.rb
|