dscf-marketplace 0.1.9 → 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.
- checksums.yaml +4 -4
- data/app/controllers/dscf/marketplace/delivery_order_items_controller.rb +64 -0
- data/app/controllers/dscf/marketplace/delivery_orders_controller.rb +72 -0
- data/app/controllers/dscf/marketplace/delivery_vehicles_controller.rb +28 -0
- data/app/controllers/dscf/marketplace/order_items_controller.rb +29 -0
- data/app/controllers/dscf/marketplace/quotation_items_controller.rb +28 -0
- data/app/controllers/dscf/marketplace/rfq_items_controller.rb +28 -0
- data/app/controllers/dscf/marketplace/supplier_products_controller.rb +29 -0
- data/app/controllers/dscf/marketplace/unit_conversions_controller.rb +28 -0
- data/app/controllers/dscf/marketplace/units_controller.rb +26 -0
- data/app/models/dscf/marketplace/delivery_order.rb +6 -0
- data/app/models/dscf/marketplace/quotation_item.rb +42 -10
- data/app/serializers/dscf/marketplace/delivery_order_item_serializer.rb +17 -0
- data/app/serializers/dscf/marketplace/delivery_order_serializer.rb +17 -0
- data/app/serializers/dscf/marketplace/delivery_vehicle_serializer.rb +12 -0
- data/app/serializers/dscf/marketplace/order_item_serializer.rb +16 -0
- data/app/serializers/dscf/marketplace/quotation_item_serializer.rb +16 -0
- data/app/serializers/dscf/marketplace/rfq_item_serializer.rb +14 -0
- data/app/serializers/dscf/marketplace/supplier_product_serializer.rb +13 -0
- data/app/serializers/dscf/marketplace/unit_conversion_serializer.rb +11 -0
- data/app/serializers/dscf/marketplace/unit_serializer.rb +9 -0
- data/config/routes.rb +4 -4
- data/lib/dscf/marketplace/version.rb +1 -1
- data/spec/factories/dscf/marketplace/delivery_order_items.rb +1 -1
- data/spec/factories/dscf/marketplace/quotation_items.rb +2 -2
- metadata +19 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: df198307c66d8356b9c6087b33670c4658047882587a996d835cd993688f1928
|
4
|
+
data.tar.gz: 5e020f16c458e74f374462d732c6fe746e5cd122489b4b3c5bff026a9845bd1b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5a504501c9c8235f1a634e8f0b62c527c1383c87fa36f08c79e2f89e22c4ced206b63bbc80330eb11a44e141dea08ebae506a97f2dcb565ad4dbd7ab58544405
|
7
|
+
data.tar.gz: df8f9d49b2d9a47cdf68a87e12d07497d8ccffa08a5ee9678982ba5fbc468924a24245f844dfa8a1976f6cda468f91b022cd367a9ef573cbcda7a1eb19d242b6
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Dscf
|
2
|
+
module Marketplace
|
3
|
+
class DeliveryOrderItemsController < ApplicationController
|
4
|
+
include Dscf::Core::Common
|
5
|
+
|
6
|
+
def receiver_confirm
|
7
|
+
@obj = find_record
|
8
|
+
if @obj.receiver_confirm!(params[:confirmed_quantity], params[:notes], current_user&.id)
|
9
|
+
render_success("delivery_order_items.success.receiver_confirmed", data: @obj)
|
10
|
+
else
|
11
|
+
render_error("delivery_order_items.errors.receiver_confirm_failed")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def report_issue
|
16
|
+
@obj = find_record
|
17
|
+
issue_type = params[:issue_type]
|
18
|
+
quantity = params[:quantity]
|
19
|
+
description = params[:description]
|
20
|
+
|
21
|
+
if @obj.report_issue!(issue_type, quantity, description, current_user&.id)
|
22
|
+
render_success("delivery_order_items.success.issue_reported", data: @obj)
|
23
|
+
else
|
24
|
+
render_error("delivery_order_items.errors.report_issue_failed")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def dispute_delivery
|
29
|
+
@obj = find_record
|
30
|
+
reason = params[:reason]
|
31
|
+
|
32
|
+
if @obj.dispute_delivery!(reason, current_user&.id)
|
33
|
+
render_success("delivery_order_items.success.delivery_disputed", data: @obj)
|
34
|
+
else
|
35
|
+
render_error("delivery_order_items.errors.dispute_delivery_failed")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def model_params
|
42
|
+
params.require(:delivery_order_item).permit(
|
43
|
+
:delivery_order_id, :order_item_id, :pickup_address_id, :dropoff_address_id,
|
44
|
+
:quantity, :status, :pickup_verified_quantity, :dropoff_verified_quantity,
|
45
|
+
:damaged_quantity, :missing_quantity, :receiver_confirmed_by,
|
46
|
+
:receiver_confirmed_at, :receiver_notes, :handoff_checklist_completed
|
47
|
+
)
|
48
|
+
end
|
49
|
+
|
50
|
+
def eager_loaded_associations
|
51
|
+
[ :delivery_order, :order_item, :pickup_address, :dropoff_address ]
|
52
|
+
end
|
53
|
+
|
54
|
+
def default_serializer_includes
|
55
|
+
{
|
56
|
+
index: [ :delivery_order, :order_item ],
|
57
|
+
show: [ :delivery_order, :order_item, :pickup_address, :dropoff_address ],
|
58
|
+
create: [ :delivery_order, :order_item ],
|
59
|
+
update: [ :delivery_order, :order_item ]
|
60
|
+
}
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Dscf
|
2
|
+
module Marketplace
|
3
|
+
class DeliveryOrdersController < ApplicationController
|
4
|
+
include Dscf::Core::Common
|
5
|
+
|
6
|
+
def index
|
7
|
+
@objs = DeliveryOrder.all
|
8
|
+
render_success("delivery_orders.index.success", data: @objs, serializer_options: {include: default_serializer_includes[:index]})
|
9
|
+
end
|
10
|
+
|
11
|
+
def pickup
|
12
|
+
@obj = find_record
|
13
|
+
if @obj.pickup!
|
14
|
+
render_success("delivery_orders.success.picked_up", data: @obj)
|
15
|
+
else
|
16
|
+
render_error("delivery_orders.errors.pickup_failed")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def start_delivery
|
21
|
+
@obj = find_record
|
22
|
+
if @obj.start_delivery!
|
23
|
+
render_success("delivery_orders.success.delivery_started", data: @obj)
|
24
|
+
else
|
25
|
+
render_error("delivery_orders.errors.start_delivery_failed")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def complete_delivery
|
30
|
+
@obj = find_record
|
31
|
+
if @obj.complete_delivery!
|
32
|
+
render_success("delivery_orders.success.delivery_completed", data: @obj)
|
33
|
+
else
|
34
|
+
render_error("delivery_orders.errors.complete_delivery_failed")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def mark_failed
|
39
|
+
@obj = find_record
|
40
|
+
reason = params[:reason]
|
41
|
+
if @obj.mark_failed!(reason)
|
42
|
+
render_success("delivery_orders.success.marked_failed", data: @obj)
|
43
|
+
else
|
44
|
+
render_error("delivery_orders.errors.mark_failed_failed")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def model_params
|
51
|
+
params.require(:delivery_order).permit(
|
52
|
+
:driver_id, :pickup_address_id, :delivery_vehicle_id, :status,
|
53
|
+
:vehicle_type, :estimated_delivery_price, :actual_delivery_price,
|
54
|
+
:estimated_delivery_time, :actual_delivery_time, :delivery_notes
|
55
|
+
)
|
56
|
+
end
|
57
|
+
|
58
|
+
def eager_loaded_associations
|
59
|
+
[ :driver, :pickup_address, :delivery_vehicle, :delivery_order_items, :marketplace_orders ]
|
60
|
+
end
|
61
|
+
|
62
|
+
def default_serializer_includes
|
63
|
+
{
|
64
|
+
index: [ :driver, :pickup_address, :delivery_vehicle ],
|
65
|
+
show: [ :driver, :pickup_address, :delivery_vehicle, :delivery_order_items, :marketplace_orders ],
|
66
|
+
create: [ :driver, :pickup_address, :delivery_vehicle ],
|
67
|
+
update: [ :driver, :pickup_address, :delivery_vehicle ]
|
68
|
+
}
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Dscf
|
2
|
+
module Marketplace
|
3
|
+
class DeliveryVehiclesController < ApplicationController
|
4
|
+
include Dscf::Core::Common
|
5
|
+
|
6
|
+
private
|
7
|
+
|
8
|
+
def model_params
|
9
|
+
params.require(:delivery_vehicle).permit(
|
10
|
+
:driver_id, :plate_number, :vehicle_type, :year, :brand, :model, :color
|
11
|
+
)
|
12
|
+
end
|
13
|
+
|
14
|
+
def eager_loaded_associations
|
15
|
+
[ :driver, :delivery_orders ]
|
16
|
+
end
|
17
|
+
|
18
|
+
def default_serializer_includes
|
19
|
+
{
|
20
|
+
index: [ :driver ],
|
21
|
+
show: [ :driver, :delivery_orders ],
|
22
|
+
create: [ :driver ],
|
23
|
+
update: [ :driver ]
|
24
|
+
}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Dscf
|
2
|
+
module Marketplace
|
3
|
+
class OrderItemsController < ApplicationController
|
4
|
+
include Dscf::Core::Common
|
5
|
+
|
6
|
+
private
|
7
|
+
|
8
|
+
def model_params
|
9
|
+
params.require(:order_item).permit(
|
10
|
+
:order_id, :quotation_item_id, :listing_id,
|
11
|
+
:product_id, :unit_id, :quantity, :unit_price, :status
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
def eager_loaded_associations
|
16
|
+
[ :order, :quotation_item, :listing, :product, :unit ]
|
17
|
+
end
|
18
|
+
|
19
|
+
def default_serializer_includes
|
20
|
+
{
|
21
|
+
index: [ :product, :unit ],
|
22
|
+
show: [ :order, :quotation_item, :listing, :product, :unit ],
|
23
|
+
create: [ :product, :unit ],
|
24
|
+
update: [ :product, :unit ]
|
25
|
+
}
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Dscf
|
2
|
+
module Marketplace
|
3
|
+
class QuotationItemsController < ApplicationController
|
4
|
+
include Dscf::Core::Common
|
5
|
+
|
6
|
+
private
|
7
|
+
|
8
|
+
def model_params
|
9
|
+
params.require(:quotation_item).permit(
|
10
|
+
:quotation_id, :rfq_item_id, :product_id, :unit_id, :quantity, :unit_price
|
11
|
+
)
|
12
|
+
end
|
13
|
+
|
14
|
+
def eager_loaded_associations
|
15
|
+
[ :quotation, :rfq_item, :product, :unit ]
|
16
|
+
end
|
17
|
+
|
18
|
+
def default_serializer_includes
|
19
|
+
{
|
20
|
+
index: [ :quotation, :rfq_item, :product, :unit ],
|
21
|
+
show: [ :quotation, :rfq_item, :product, :unit ],
|
22
|
+
create: [ :quotation, :rfq_item, :product, :unit ],
|
23
|
+
update: [ :quotation, :rfq_item, :product, :unit ]
|
24
|
+
}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Dscf
|
2
|
+
module Marketplace
|
3
|
+
class RfqItemsController < ApplicationController
|
4
|
+
include Dscf::Core::Common
|
5
|
+
|
6
|
+
private
|
7
|
+
|
8
|
+
def model_params
|
9
|
+
params.require(:rfq_item).permit(
|
10
|
+
:request_for_quotation_id, :product_id, :unit_id, :quantity, :notes
|
11
|
+
)
|
12
|
+
end
|
13
|
+
|
14
|
+
def eager_loaded_associations
|
15
|
+
[ :request_for_quotation, :product, :unit, :quotation_items ]
|
16
|
+
end
|
17
|
+
|
18
|
+
def default_serializer_includes
|
19
|
+
{
|
20
|
+
index: [ :request_for_quotation, :product, :unit ],
|
21
|
+
show: [ :request_for_quotation, :product, :unit, :quotation_items ],
|
22
|
+
create: [ :request_for_quotation, :product, :unit ],
|
23
|
+
update: [ :request_for_quotation, :product, :unit ]
|
24
|
+
}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Dscf
|
2
|
+
module Marketplace
|
3
|
+
class SupplierProductsController < ApplicationController
|
4
|
+
include Dscf::Core::Common
|
5
|
+
|
6
|
+
private
|
7
|
+
|
8
|
+
def model_params
|
9
|
+
params.require(:supplier_product).permit(
|
10
|
+
:business_id, :product_id, :supplier_price, :available_quantity,
|
11
|
+
:minimum_order_quantity, :status
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
def eager_loaded_associations
|
16
|
+
[ :business, :product, :listings ]
|
17
|
+
end
|
18
|
+
|
19
|
+
def default_serializer_includes
|
20
|
+
{
|
21
|
+
index: [ :business, :product ],
|
22
|
+
show: [ :business, :product, :listings ],
|
23
|
+
create: [ :business, :product ],
|
24
|
+
update: [ :business, :product ]
|
25
|
+
}
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Dscf
|
2
|
+
module Marketplace
|
3
|
+
class UnitConversionsController < ApplicationController
|
4
|
+
include Dscf::Core::Common
|
5
|
+
|
6
|
+
private
|
7
|
+
|
8
|
+
def model_params
|
9
|
+
params.require(:unit_conversion).permit(
|
10
|
+
:from_unit_id, :to_unit_id, :conversion_factor, :notes
|
11
|
+
)
|
12
|
+
end
|
13
|
+
|
14
|
+
def eager_loaded_associations
|
15
|
+
[ :from_unit, :to_unit ]
|
16
|
+
end
|
17
|
+
|
18
|
+
def default_serializer_includes
|
19
|
+
{
|
20
|
+
index: [ :from_unit, :to_unit ],
|
21
|
+
show: [ :from_unit, :to_unit ],
|
22
|
+
create: [ :from_unit, :to_unit ],
|
23
|
+
update: [ :from_unit, :to_unit ]
|
24
|
+
}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Dscf
|
2
|
+
module Marketplace
|
3
|
+
class UnitsController < ApplicationController
|
4
|
+
include Dscf::Core::Common
|
5
|
+
|
6
|
+
private
|
7
|
+
|
8
|
+
def model_params
|
9
|
+
params.require(:unit).permit(:code, :name, :unit_type)
|
10
|
+
end
|
11
|
+
|
12
|
+
def eager_loaded_associations
|
13
|
+
[ :unit_conversions ]
|
14
|
+
end
|
15
|
+
|
16
|
+
def default_serializer_includes
|
17
|
+
{
|
18
|
+
index: [ :unit_conversions ],
|
19
|
+
show: [ :unit_conversions ],
|
20
|
+
create: [],
|
21
|
+
update: []
|
22
|
+
}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -23,6 +23,12 @@ module Dscf::Marketplace
|
|
23
23
|
%w[id driver_id pickup_address_id delivery_vehicle_id status vehicle_type estimated_delivery_price actual_delivery_price estimated_delivery_time actual_delivery_time delivery_notes created_at updated_at]
|
24
24
|
end
|
25
25
|
|
26
|
+
# Override ransack to handle JSON fields
|
27
|
+
def self.ransack(params = {}, options = {})
|
28
|
+
params ||= {}
|
29
|
+
super(params.except("optimized_route"), options)
|
30
|
+
end
|
31
|
+
|
26
32
|
def self.ransackable_associations(_auth_object = nil)
|
27
33
|
%w[driver pickup_address delivery_vehicle delivery_order_items marketplace_orders]
|
28
34
|
end
|
@@ -13,13 +13,10 @@ module Dscf
|
|
13
13
|
validates :unit_id, presence: true
|
14
14
|
validates :unit_price, numericality: {greater_than: 0}, allow_nil: true
|
15
15
|
validates :subtotal, numericality: {greater_than_or_equal_to: 0}, allow_nil: true
|
16
|
-
|
17
16
|
validate :product_matches_rfq_item
|
18
17
|
validate :unit_compatible_with_product
|
19
|
-
before_save :calculate_subtotal, if: :unit_price_changed?
|
20
|
-
|
21
|
-
# Only validate subtotal calculation if both unit_price and quantity are present
|
22
18
|
validate :subtotal_matches_calculation, if: :should_validate_subtotal?
|
19
|
+
before_save :calculate_subtotal, if: :should_recalculate_subtotal?
|
23
20
|
|
24
21
|
scope :priced, -> { where.not(unit_price: nil) }
|
25
22
|
scope :unpriced, -> { where(unit_price: nil) }
|
@@ -76,8 +73,7 @@ module Dscf
|
|
76
73
|
def matches_rfq_request?
|
77
74
|
return false unless rfq_item
|
78
75
|
|
79
|
-
product_id == rfq_item.product_id &&
|
80
|
-
unit_id == rfq_item.unit_id
|
76
|
+
product_id == rfq_item.product_id && unit_id == rfq_item.unit_id
|
81
77
|
end
|
82
78
|
|
83
79
|
def can_create_order?
|
@@ -89,8 +85,35 @@ module Dscf
|
|
89
85
|
def calculate_subtotal
|
90
86
|
return unless unit_price && quantity
|
91
87
|
|
92
|
-
self.subtotal = unit_price * quantity
|
88
|
+
self.subtotal = (unit_price * quantity).round(2)
|
89
|
+
end
|
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
|
93
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
|
94
117
|
|
95
118
|
def product_matches_rfq_item
|
96
119
|
return unless rfq_item_id && product_id
|
@@ -111,14 +134,23 @@ module Dscf
|
|
111
134
|
def subtotal_matches_calculation
|
112
135
|
return unless should_validate_subtotal?
|
113
136
|
|
114
|
-
|
115
|
-
|
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
|
116
143
|
errors.add(:subtotal, "must equal unit_price * quantity")
|
117
144
|
end
|
118
145
|
end
|
119
146
|
|
120
147
|
def should_validate_subtotal?
|
121
|
-
|
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?
|
122
154
|
end
|
123
155
|
end
|
124
156
|
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,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,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 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
|
data/config/routes.rb
CHANGED
@@ -39,7 +39,7 @@ Dscf::Marketplace::Engine.routes.draw do
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
-
resources :rfq_items, only: [ :show, :update, :destroy ]
|
42
|
+
resources :rfq_items, only: [ :index, :show, :update, :create, :destroy ]
|
43
43
|
|
44
44
|
resources :quotations do
|
45
45
|
resources :quotation_items, only: [ :index, :create ]
|
@@ -50,7 +50,7 @@ Dscf::Marketplace::Engine.routes.draw do
|
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
|
-
resources :quotation_items, only: [ :show, :update, :destroy ]
|
53
|
+
resources :quotation_items, only: [ :index, :show, :update, :create, :destroy ]
|
54
54
|
|
55
55
|
# Order Management
|
56
56
|
resources :orders do
|
@@ -62,7 +62,7 @@ Dscf::Marketplace::Engine.routes.draw do
|
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
|
-
resources :order_items, only: [ :show, :update ]
|
65
|
+
resources :order_items, only: [ :index, :show, :update, :create, :destroy ]
|
66
66
|
|
67
67
|
# Delivery System
|
68
68
|
resources :delivery_orders do
|
@@ -75,7 +75,7 @@ Dscf::Marketplace::Engine.routes.draw do
|
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
78
|
-
resources :delivery_order_items, only: [ :show, :update ] do
|
78
|
+
resources :delivery_order_items, only: [ :index, :show, :update, :create ] do
|
79
79
|
member do
|
80
80
|
post "receiver_confirm"
|
81
81
|
post "report_issue"
|
@@ -1,7 +1,7 @@
|
|
1
1
|
FactoryBot.define do
|
2
2
|
factory :dscf_marketplace_delivery_order_item, class: "Dscf::Marketplace::DeliveryOrderItem" do
|
3
3
|
association :delivery_order, factory: :dscf_marketplace_delivery_order
|
4
|
-
association :order_item, factory: :dscf_marketplace_order_item
|
4
|
+
association :order_item, factory: [ :dscf_marketplace_order_item, :from_listing ]
|
5
5
|
pickup_address { create(:dscf_core_address) }
|
6
6
|
dropoff_address { create(:dscf_core_address) }
|
7
7
|
quantity { 10.0 }
|
@@ -10,8 +10,8 @@ FactoryBot.define do
|
|
10
10
|
|
11
11
|
after(:build) do |item|
|
12
12
|
# Only calculate subtotal if it's not explicitly set
|
13
|
-
if item
|
14
|
-
item.subtotal = item.unit_price * item.quantity
|
13
|
+
if item[:subtotal].nil? && item.unit_price && item.quantity
|
14
|
+
item.subtotal = (item.unit_price * item.quantity).round(2)
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
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.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Asrat
|
@@ -418,11 +418,20 @@ files:
|
|
418
418
|
- Rakefile
|
419
419
|
- app/controllers/dscf/marketplace/application_controller.rb
|
420
420
|
- app/controllers/dscf/marketplace/categories_controller.rb
|
421
|
+
- app/controllers/dscf/marketplace/delivery_order_items_controller.rb
|
422
|
+
- app/controllers/dscf/marketplace/delivery_orders_controller.rb
|
423
|
+
- app/controllers/dscf/marketplace/delivery_vehicles_controller.rb
|
421
424
|
- app/controllers/dscf/marketplace/listings_controller.rb
|
425
|
+
- app/controllers/dscf/marketplace/order_items_controller.rb
|
422
426
|
- app/controllers/dscf/marketplace/orders_controller.rb
|
423
427
|
- app/controllers/dscf/marketplace/products_controller.rb
|
428
|
+
- app/controllers/dscf/marketplace/quotation_items_controller.rb
|
424
429
|
- app/controllers/dscf/marketplace/quotations_controller.rb
|
425
430
|
- app/controllers/dscf/marketplace/request_for_quotations_controller.rb
|
431
|
+
- app/controllers/dscf/marketplace/rfq_items_controller.rb
|
432
|
+
- app/controllers/dscf/marketplace/supplier_products_controller.rb
|
433
|
+
- app/controllers/dscf/marketplace/unit_conversions_controller.rb
|
434
|
+
- app/controllers/dscf/marketplace/units_controller.rb
|
426
435
|
- app/jobs/dscf/marketplace/application_job.rb
|
427
436
|
- app/mailers/dscf/marketplace/application_mailer.rb
|
428
437
|
- app/models/dscf/marketplace/application_record.rb
|
@@ -442,11 +451,20 @@ files:
|
|
442
451
|
- app/models/dscf/marketplace/unit.rb
|
443
452
|
- app/models/dscf/marketplace/unit_conversion.rb
|
444
453
|
- app/serializers/dscf/marketplace/category_serializer.rb
|
454
|
+
- app/serializers/dscf/marketplace/delivery_order_item_serializer.rb
|
455
|
+
- app/serializers/dscf/marketplace/delivery_order_serializer.rb
|
456
|
+
- app/serializers/dscf/marketplace/delivery_vehicle_serializer.rb
|
445
457
|
- app/serializers/dscf/marketplace/listing_serializer.rb
|
458
|
+
- app/serializers/dscf/marketplace/order_item_serializer.rb
|
446
459
|
- app/serializers/dscf/marketplace/order_serializer.rb
|
447
460
|
- app/serializers/dscf/marketplace/product_serializer.rb
|
461
|
+
- app/serializers/dscf/marketplace/quotation_item_serializer.rb
|
448
462
|
- app/serializers/dscf/marketplace/quotation_serializer.rb
|
449
463
|
- app/serializers/dscf/marketplace/request_for_quotation_serializer.rb
|
464
|
+
- app/serializers/dscf/marketplace/rfq_item_serializer.rb
|
465
|
+
- app/serializers/dscf/marketplace/supplier_product_serializer.rb
|
466
|
+
- app/serializers/dscf/marketplace/unit_conversion_serializer.rb
|
467
|
+
- app/serializers/dscf/marketplace/unit_serializer.rb
|
450
468
|
- config/locales/en.yml
|
451
469
|
- config/routes.rb
|
452
470
|
- db/migrate/20250827172043_create_dscf_marketplace_categories.rb
|