dscf-marketplace 0.1.8 → 0.2.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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/dscf/marketplace/application_controller.rb +2 -0
  3. data/app/controllers/dscf/marketplace/categories_controller.rb +26 -0
  4. data/app/controllers/dscf/marketplace/delivery_order_items_controller.rb +64 -0
  5. data/app/controllers/dscf/marketplace/delivery_orders_controller.rb +72 -0
  6. data/app/controllers/dscf/marketplace/delivery_vehicles_controller.rb +28 -0
  7. data/app/controllers/dscf/marketplace/listings_controller.rb +55 -0
  8. data/app/controllers/dscf/marketplace/order_items_controller.rb +29 -0
  9. data/app/controllers/dscf/marketplace/orders_controller.rb +58 -0
  10. data/app/controllers/dscf/marketplace/products_controller.rb +30 -0
  11. data/app/controllers/dscf/marketplace/quotation_items_controller.rb +28 -0
  12. data/app/controllers/dscf/marketplace/quotations_controller.rb +56 -0
  13. data/app/controllers/dscf/marketplace/request_for_quotations_controller.rb +46 -0
  14. data/app/controllers/dscf/marketplace/rfq_items_controller.rb +28 -0
  15. data/app/controllers/dscf/marketplace/supplier_products_controller.rb +29 -0
  16. data/app/controllers/dscf/marketplace/unit_conversions_controller.rb +28 -0
  17. data/app/controllers/dscf/marketplace/units_controller.rb +26 -0
  18. data/app/models/dscf/marketplace/category.rb +9 -0
  19. data/app/models/dscf/marketplace/delivery_order.rb +15 -0
  20. data/app/models/dscf/marketplace/delivery_order_item.rb +9 -0
  21. data/app/models/dscf/marketplace/delivery_vehicle.rb +9 -0
  22. data/app/models/dscf/marketplace/listing.rb +9 -0
  23. data/app/models/dscf/marketplace/order.rb +9 -0
  24. data/app/models/dscf/marketplace/order_item.rb +9 -0
  25. data/app/models/dscf/marketplace/product.rb +9 -0
  26. data/app/models/dscf/marketplace/quotation.rb +9 -0
  27. data/app/models/dscf/marketplace/quotation_item.rb +51 -12
  28. data/app/models/dscf/marketplace/request_for_quotation.rb +9 -0
  29. data/app/models/dscf/marketplace/rfq_item.rb +9 -0
  30. data/app/models/dscf/marketplace/supplier_product.rb +9 -0
  31. data/app/models/dscf/marketplace/unit.rb +9 -0
  32. data/app/models/dscf/marketplace/unit_conversion.rb +9 -0
  33. data/app/serializers/dscf/marketplace/category_serializer.rb +11 -0
  34. data/app/serializers/dscf/marketplace/delivery_order_item_serializer.rb +17 -0
  35. data/app/serializers/dscf/marketplace/delivery_order_serializer.rb +17 -0
  36. data/app/serializers/dscf/marketplace/delivery_vehicle_serializer.rb +12 -0
  37. data/app/serializers/dscf/marketplace/listing_serializer.rb +13 -0
  38. data/app/serializers/dscf/marketplace/order_item_serializer.rb +16 -0
  39. data/app/serializers/dscf/marketplace/order_serializer.rb +15 -0
  40. data/app/serializers/dscf/marketplace/product_serializer.rb +13 -0
  41. data/app/serializers/dscf/marketplace/quotation_item_serializer.rb +16 -0
  42. data/app/serializers/dscf/marketplace/quotation_serializer.rb +14 -0
  43. data/app/serializers/dscf/marketplace/request_for_quotation_serializer.rb +13 -0
  44. data/app/serializers/dscf/marketplace/rfq_item_serializer.rb +14 -0
  45. data/app/serializers/dscf/marketplace/supplier_product_serializer.rb +13 -0
  46. data/app/serializers/dscf/marketplace/unit_conversion_serializer.rb +11 -0
  47. data/app/serializers/dscf/marketplace/unit_serializer.rb +9 -0
  48. data/config/locales/en.yml +254 -0
  49. data/config/routes.rb +85 -0
  50. data/lib/dscf/marketplace/version.rb +1 -1
  51. data/spec/factories/dscf/marketplace/delivery_order_items.rb +1 -1
  52. data/spec/factories/dscf/marketplace/quotation_items.rb +2 -2
  53. metadata +32 -1
@@ -20,6 +20,15 @@ module Dscf::Marketplace
20
20
 
21
21
  before_save :calculate_verification_totals
22
22
 
23
+ # Ransack configuration for secure filtering
24
+ def self.ransackable_attributes(_auth_object = nil)
25
+ %w[id delivery_order_id order_item_id pickup_address_id dropoff_address_id quantity status pickup_verified_quantity dropoff_verified_quantity damaged_quantity missing_quantity receiver_confirmed_by receiver_confirmed_at receiver_notes handoff_checklist_completed created_at updated_at]
26
+ end
27
+
28
+ def self.ransackable_associations(_auth_object = nil)
29
+ %w[delivery_order order_item pickup_address dropoff_address]
30
+ end
31
+
23
32
  def pending?
24
33
  status == "pending"
25
34
  end
@@ -14,6 +14,15 @@ module Dscf
14
14
  validates :model, length: {maximum: 50}, allow_blank: true
15
15
  validates :color, length: {maximum: 30}, allow_blank: true
16
16
 
17
+ # Ransack configuration for secure filtering
18
+ def self.ransackable_attributes(_auth_object = nil)
19
+ %w[id driver_id plate_number vehicle_type year brand model color created_at updated_at]
20
+ end
21
+
22
+ def self.ransackable_associations(_auth_object = nil)
23
+ %w[driver delivery_orders]
24
+ end
25
+
17
26
  def motorcycle?
18
27
  vehicle_type == "motorcycle"
19
28
  end
@@ -21,6 +21,15 @@ module Dscf::Marketplace
21
21
  scope :by_business, ->(business_id) { where(business_id: business_id) }
22
22
  scope :owned_by, ->(business) { where(business: business) }
23
23
 
24
+ # Ransack configuration for secure filtering
25
+ def self.ransackable_attributes(_auth_object = nil)
26
+ %w[id business_id supplier_product_id price quantity status created_at updated_at]
27
+ end
28
+
29
+ def self.ransackable_associations(_auth_object = nil)
30
+ %w[business supplier_product order_items]
31
+ end
32
+
24
33
  # Custom methods
25
34
  def total_value
26
35
  price * quantity
@@ -18,6 +18,15 @@ module Dscf::Marketplace
18
18
 
19
19
  before_save :calculate_total_amount
20
20
 
21
+ # Ransack configuration for secure filtering
22
+ def self.ransackable_attributes(_auth_object = nil)
23
+ %w[id quotation_id listing_id user_id delivery_order_id order_type status fulfillment_type total_amount created_at updated_at]
24
+ end
25
+
26
+ def self.ransackable_associations(_auth_object = nil)
27
+ %w[quotation listing user delivery_order order_items]
28
+ end
29
+
21
30
  def self.create_from_quotation(quotation)
22
31
  return nil unless quotation.accepted?
23
32
 
@@ -15,6 +15,15 @@ module Dscf::Marketplace
15
15
  validates :unit, presence: true
16
16
  validate :quotation_item_or_listing_present
17
17
 
18
+ # Ransack configuration for secure filtering
19
+ def self.ransackable_attributes(_auth_object = nil)
20
+ %w[id order_id quotation_item_id listing_id product_id unit_id quantity unit_price status created_at updated_at]
21
+ end
22
+
23
+ def self.ransackable_associations(_auth_object = nil)
24
+ %w[order quotation_item listing product unit]
25
+ end
26
+
18
27
  def subtotal
19
28
  quantity * unit_price
20
29
  end
@@ -27,6 +27,15 @@ module Dscf
27
27
  scope :by_category, ->(category_id) { where(category_id: category_id) }
28
28
  scope :by_unit, ->(unit_id) { where(unit_id: unit_id) }
29
29
 
30
+ # Ransack configuration for secure filtering
31
+ def self.ransackable_attributes(_auth_object = nil)
32
+ %w[id sku name description category_id unit_id base_price base_quantity business_only created_at updated_at]
33
+ end
34
+
35
+ def self.ransackable_associations(_auth_object = nil)
36
+ %w[category unit supplier_products listings order_items rfq_items quotation_items]
37
+ end
38
+
30
39
  def display_name
31
40
  "#{name} (#{sku})"
32
41
  end
@@ -22,6 +22,15 @@ module Dscf
22
22
  scope :valid_quotations, -> { where("valid_until > ?", Time.current) }
23
23
  scope :expired_quotations, -> { where("valid_until <= ?", Time.current) }
24
24
 
25
+ # Ransack configuration for secure filtering
26
+ def self.ransackable_attributes(_auth_object = nil)
27
+ %w[id request_for_quotation_id business_id total_price delivery_date valid_until status notes created_at updated_at]
28
+ end
29
+
30
+ def self.ransackable_associations(_auth_object = nil)
31
+ %w[request_for_quotation business quotation_items order]
32
+ end
33
+
25
34
  def calculate_total_price
26
35
  self.total_price = quotation_items.sum(&:subtotal).to_f
27
36
  end
@@ -6,8 +6,6 @@ module Dscf
6
6
  belongs_to :product, class_name: "Dscf::Marketplace::Product"
7
7
  belongs_to :unit, class_name: "Dscf::Marketplace::Unit"
8
8
 
9
-
10
-
11
9
  validates :quotation_id, presence: true
12
10
  validates :rfq_item_id, presence: true
13
11
  validates :product_id, presence: true
@@ -15,19 +13,25 @@ module Dscf
15
13
  validates :unit_id, presence: true
16
14
  validates :unit_price, numericality: {greater_than: 0}, allow_nil: true
17
15
  validates :subtotal, numericality: {greater_than_or_equal_to: 0}, allow_nil: true
18
-
19
16
  validate :product_matches_rfq_item
20
17
  validate :unit_compatible_with_product
21
- before_save :calculate_subtotal, if: :unit_price_changed?
22
-
23
- # Only validate subtotal calculation if both unit_price and quantity are present
24
18
  validate :subtotal_matches_calculation, if: :should_validate_subtotal?
19
+ before_save :calculate_subtotal, if: :should_recalculate_subtotal?
25
20
 
26
21
  scope :priced, -> { where.not(unit_price: nil) }
27
22
  scope :unpriced, -> { where(unit_price: nil) }
28
23
  scope :by_product, ->(product_id) { where(product_id: product_id) }
29
24
  scope :by_unit, ->(unit_id) { where(unit_id: unit_id) }
30
25
 
26
+ # Ransack configuration for secure filtering
27
+ def self.ransackable_attributes(_auth_object = nil)
28
+ %w[id quotation_id rfq_item_id product_id unit_id quantity unit_price subtotal created_at updated_at]
29
+ end
30
+
31
+ def self.ransackable_associations(_auth_object = nil)
32
+ %w[quotation rfq_item product unit]
33
+ end
34
+
31
35
  def product_name
32
36
  product&.name
33
37
  end
@@ -69,8 +73,7 @@ module Dscf
69
73
  def matches_rfq_request?
70
74
  return false unless rfq_item
71
75
 
72
- product_id == rfq_item.product_id &&
73
- unit_id == rfq_item.unit_id
76
+ product_id == rfq_item.product_id && unit_id == rfq_item.unit_id
74
77
  end
75
78
 
76
79
  def can_create_order?
@@ -82,9 +85,36 @@ module Dscf
82
85
  def calculate_subtotal
83
86
  return unless unit_price && quantity
84
87
 
85
- self.subtotal = unit_price * quantity
88
+ self.subtotal = (unit_price * quantity).round(2)
86
89
  end
87
90
 
91
+ # Calculate subtotal automatically if not set
92
+ def calculated_subtotal
93
+ return subtotal if subtotal.present?
94
+ return nil unless unit_price && quantity
95
+
96
+ (unit_price * quantity).round(2)
97
+ end
98
+
99
+ # Override subtotal setter to allow validation to work
100
+ def subtotal=(value)
101
+ # Allow any value to be set for validation purposes
102
+ super
103
+ end
104
+ public :subtotal=
105
+
106
+ # Override subtotal getter to calculate if not set
107
+ def subtotal
108
+ stored_value = super
109
+ # If we have a stored value (including 0), return it
110
+ # Only calculate if it's nil and we have the required fields
111
+ return stored_value unless stored_value.nil?
112
+ return nil unless unit_price && quantity
113
+
114
+ (unit_price * quantity).round(2)
115
+ end
116
+ public :subtotal
117
+
88
118
  def product_matches_rfq_item
89
119
  return unless rfq_item_id && product_id
90
120
 
@@ -104,14 +134,23 @@ module Dscf
104
134
  def subtotal_matches_calculation
105
135
  return unless should_validate_subtotal?
106
136
 
107
- expected_subtotal = unit_price * quantity
108
- unless subtotal == expected_subtotal
137
+ # Calculate what the subtotal should be based on current unit_price and quantity
138
+ expected_subtotal = (unit_price * quantity).round(2)
139
+
140
+ # If subtotal is stored and doesn't match, that's an error
141
+ # If subtotal is nil, we'll let the before_save callback handle it
142
+ if subtotal.present? && subtotal.round(2) != expected_subtotal
109
143
  errors.add(:subtotal, "must equal unit_price * quantity")
110
144
  end
111
145
  end
112
146
 
113
147
  def should_validate_subtotal?
114
- unit_price.present? && quantity.present? && subtotal.present?
148
+ # Only validate if subtotal is explicitly set and we have unit_price and quantity
149
+ unit_price.present? && quantity.present? && subtotal.present? && subtotal_changed?
150
+ end
151
+
152
+ def should_recalculate_subtotal?
153
+ unit_price_changed? || quantity_changed?
115
154
  end
116
155
  end
117
156
  end
@@ -14,6 +14,15 @@ module Dscf
14
14
  validate :selected_quotation_belongs_to_this_rfq
15
15
  scope :by_user, ->(user_id) { where(user_id: user_id) }
16
16
 
17
+ # Ransack configuration for secure filtering
18
+ def self.ransackable_attributes(_auth_object = nil)
19
+ %w[id user_id selected_quotation_id status notes created_at updated_at]
20
+ end
21
+
22
+ def self.ransackable_associations(_auth_object = nil)
23
+ %w[user selected_quotation rfq_items quotations]
24
+ end
25
+
17
26
  def draft?
18
27
  status == "draft"
19
28
  end
@@ -18,6 +18,15 @@ module Dscf
18
18
  scope :by_product, ->(product_id) { where(product_id: product_id) }
19
19
  scope :by_unit, ->(unit_id) { where(unit_id: unit_id) }
20
20
 
21
+ # Ransack configuration for secure filtering
22
+ def self.ransackable_attributes(_auth_object = nil)
23
+ %w[id request_for_quotation_id product_id unit_id quantity notes created_at updated_at]
24
+ end
25
+
26
+ def self.ransackable_associations(_auth_object = nil)
27
+ %w[request_for_quotation product unit quotation_items]
28
+ end
29
+
21
30
  def product_name
22
31
  product&.name
23
32
  end
@@ -22,6 +22,15 @@ module Dscf::Marketplace
22
22
  scope :by_business, ->(business_id) { where(business_id: business_id) }
23
23
  scope :by_product, ->(product_id) { where(product_id: product_id) }
24
24
 
25
+ # Ransack configuration for secure filtering
26
+ def self.ransackable_attributes(_auth_object = nil)
27
+ %w[id business_id product_id supplier_price available_quantity minimum_order_quantity status created_at updated_at]
28
+ end
29
+
30
+ def self.ransackable_associations(_auth_object = nil)
31
+ %w[business product listings order_items]
32
+ end
33
+
25
34
  # Custom methods
26
35
  def in_stock?
27
36
  available_quantity > 0
@@ -24,6 +24,15 @@ module Dscf
24
24
 
25
25
  scope :by_type, ->(type) { where(unit_type: unit_types[type]) }
26
26
 
27
+ # Ransack configuration for secure filtering
28
+ def self.ransackable_attributes(_auth_object = nil)
29
+ %w[id code name unit_type created_at updated_at]
30
+ end
31
+
32
+ def self.ransackable_associations(_auth_object = nil)
33
+ %w[unit_conversions products supplier_products listings order_items rfq_items quotation_items]
34
+ end
35
+
27
36
  def display_name
28
37
  "#{name} (#{code})"
29
38
  end
@@ -11,6 +11,15 @@ module Dscf
11
11
 
12
12
  validate :units_must_be_different
13
13
 
14
+ # Ransack configuration for secure filtering
15
+ def self.ransackable_attributes(_auth_object = nil)
16
+ %w[id from_unit_id to_unit_id conversion_factor notes created_at updated_at]
17
+ end
18
+
19
+ def self.ransackable_associations(_auth_object = nil)
20
+ %w[from_unit to_unit]
21
+ end
22
+
14
23
  def units_must_be_different
15
24
  return unless from_unit_id && to_unit_id
16
25
 
@@ -0,0 +1,11 @@
1
+ module Dscf
2
+ module Marketplace
3
+ class CategorySerializer < ActiveModel::Serializer
4
+ attributes :id, :name, :description, :parent_id, :created_at, :updated_at
5
+
6
+ belongs_to :parent, serializer: CategorySerializer
7
+ has_many :subcategories, serializer: CategorySerializer
8
+ has_many :products
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,17 @@
1
+ module Dscf
2
+ module Marketplace
3
+ class DeliveryOrderItemSerializer < ActiveModel::Serializer
4
+ attributes :id, :delivery_order_id, :order_item_id, :pickup_address_id, :dropoff_address_id,
5
+ :quantity, :status, :pickup_verified_quantity, :dropoff_verified_quantity,
6
+ :damaged_quantity, :missing_quantity, :receiver_confirmed_by,
7
+ :receiver_confirmed_at, :receiver_notes, :handoff_checklist_completed,
8
+ :created_at, :updated_at, :product_name, :unit_name, :verification_complete?,
9
+ :has_discrepancy?, :discrepancy_amount, :requires_resolution?
10
+
11
+ belongs_to :delivery_order
12
+ belongs_to :order_item
13
+ belongs_to :pickup_address
14
+ belongs_to :dropoff_address
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module Dscf
2
+ module Marketplace
3
+ class DeliveryOrderSerializer < ActiveModel::Serializer
4
+ attributes :id, :driver_id, :pickup_address_id, :delivery_vehicle_id, :status,
5
+ :vehicle_type, :estimated_delivery_price, :actual_delivery_price,
6
+ :estimated_delivery_time, :actual_delivery_time, :delivery_notes,
7
+ :created_at, :updated_at, :total_items, :total_orders, :delivery_duration,
8
+ :on_time?, :all_handoffs_confirmed?
9
+
10
+ belongs_to :driver
11
+ belongs_to :pickup_address
12
+ belongs_to :delivery_vehicle
13
+ has_many :delivery_order_items
14
+ has_many :marketplace_orders
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,12 @@
1
+ module Dscf
2
+ module Marketplace
3
+ class DeliveryVehicleSerializer < ActiveModel::Serializer
4
+ attributes :id, :driver_id, :plate_number, :vehicle_type, :year, :brand,
5
+ :model, :color, :created_at, :updated_at, :display_name,
6
+ :total_deliveries, :success_rate
7
+
8
+ belongs_to :driver
9
+ has_many :delivery_orders
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ module Dscf
2
+ module Marketplace
3
+ class ListingSerializer < ActiveModel::Serializer
4
+ attributes :id, :business_id, :supplier_product_id, :price, :quantity,
5
+ :status, :created_at, :updated_at, :total_value, :margin,
6
+ :margin_percentage, :available?
7
+
8
+ belongs_to :business
9
+ belongs_to :supplier_product
10
+ has_many :order_items
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,16 @@
1
+ module Dscf
2
+ module Marketplace
3
+ class OrderItemSerializer < ActiveModel::Serializer
4
+ attributes :id, :order_id, :quotation_item_id, :listing_id,
5
+ :product_id, :unit_id, :quantity, :unit_price,
6
+ :status, :created_at, :updated_at,
7
+ :subtotal, :product_name, :unit_name
8
+
9
+ belongs_to :order
10
+ belongs_to :quotation_item
11
+ belongs_to :listing
12
+ belongs_to :product
13
+ belongs_to :unit
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,15 @@
1
+ module Dscf
2
+ module Marketplace
3
+ class OrderSerializer < ActiveModel::Serializer
4
+ attributes :id, :quotation_id, :listing_id, :user_id, :delivery_order_id,
5
+ :order_type, :status, :fulfillment_type, :total_amount,
6
+ :created_at, :updated_at
7
+
8
+ belongs_to :quotation
9
+ belongs_to :listing
10
+ belongs_to :user
11
+ belongs_to :delivery_order
12
+ has_many :order_items
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,13 @@
1
+ module Dscf
2
+ module Marketplace
3
+ class ProductSerializer < ActiveModel::Serializer
4
+ attributes :id, :sku, :name, :description, :category_id, :unit_id,
5
+ :base_price, :base_quantity, :business_only, :created_at, :updated_at,
6
+ :display_name, :price_per_unit, :thumbnail_url, :images_urls
7
+
8
+ belongs_to :category
9
+ belongs_to :unit
10
+ has_many :supplier_products
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,16 @@
1
+ module Dscf
2
+ module Marketplace
3
+ class QuotationItemSerializer < ActiveModel::Serializer
4
+ attributes :id, :quotation_id, :rfq_item_id, :product_id, :unit_id, :quantity,
5
+ :unit_price, :subtotal, :created_at, :updated_at, :product_name,
6
+ :product_sku, :unit_name, :unit_code, :rfq_requested_quantity,
7
+ :quantity_difference, :quantity_difference_percentage, :price_per_base_unit,
8
+ :matches_rfq_request?, :can_create_order?
9
+
10
+ belongs_to :quotation
11
+ belongs_to :rfq_item
12
+ belongs_to :product
13
+ belongs_to :unit
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,14 @@
1
+ module Dscf
2
+ module Marketplace
3
+ class QuotationSerializer < ActiveModel::Serializer
4
+ attributes :id, :request_for_quotation_id, :business_id, :total_price,
5
+ :delivery_date, :valid_until, :status, :notes, :created_at,
6
+ :updated_at, :days_until_expiry, :delivery_in_days, :complete?
7
+
8
+ belongs_to :request_for_quotation
9
+ belongs_to :business
10
+ has_many :quotation_items
11
+ has_one :order
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,13 @@
1
+ module Dscf
2
+ module Marketplace
3
+ class RequestForQuotationSerializer < ActiveModel::Serializer
4
+ attributes :id, :user_id, :selected_quotation_id, :status, :notes,
5
+ :created_at, :updated_at, :total_items, :has_responses?
6
+
7
+ belongs_to :user
8
+ belongs_to :selected_quotation
9
+ has_many :rfq_items
10
+ has_many :quotations
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ module Dscf
2
+ module Marketplace
3
+ class RfqItemSerializer < ActiveModel::Serializer
4
+ attributes :id, :request_for_quotation_id, :product_id, :unit_id, :quantity, :notes,
5
+ :created_at, :updated_at, :product_name, :product_sku, :unit_name,
6
+ :unit_code, :quotation_count, :has_quotations?, :quoted_price_range
7
+
8
+ belongs_to :request_for_quotation
9
+ belongs_to :product
10
+ belongs_to :unit
11
+ has_many :quotation_items
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,13 @@
1
+ module Dscf
2
+ module Marketplace
3
+ class SupplierProductSerializer < ActiveModel::Serializer
4
+ attributes :id, :business_id, :product_id, :supplier_price, :available_quantity,
5
+ :minimum_order_quantity, :status, :created_at, :updated_at,
6
+ :in_stock?, :price_per_unit, :display_name
7
+
8
+ belongs_to :business
9
+ belongs_to :product
10
+ has_many :listings
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,11 @@
1
+ module Dscf
2
+ module Marketplace
3
+ class UnitConversionSerializer < ActiveModel::Serializer
4
+ attributes :id, :from_unit_id, :to_unit_id, :conversion_factor, :notes,
5
+ :created_at, :updated_at, :reverse_conversion_factor, :description
6
+
7
+ belongs_to :from_unit
8
+ belongs_to :to_unit
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ module Dscf
2
+ module Marketplace
3
+ class UnitSerializer < ActiveModel::Serializer
4
+ attributes :id, :code, :name, :unit_type, :created_at, :updated_at, :display_name
5
+
6
+ has_many :unit_conversions
7
+ end
8
+ end
9
+ end