dscf-marketplace 0.3.3 → 0.3.5
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_orders_controller.rb +54 -0
- data/app/models/dscf/marketplace/delivery_order.rb +2 -2
- data/app/services/dscf/marketplace/delivery_order_service.rb +97 -0
- data/config/locales/en.yml +32 -23
- data/config/routes.rb +2 -0
- data/db/migrate/20250916083536_make_driver_id_nullable_in_delivery_orders.rb +5 -0
- data/lib/dscf/marketplace/version.rb +1 -1
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ed0561954d684647c338a26994cf4b58d0671024866a05dfa897352e4e827e65
|
4
|
+
data.tar.gz: b959f769320523fdadcdb69e58664b9879fed6ec36b563b8155363ec0cb5856e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8fbb075febd4bbbec9813858f235ad9b8be64d9e2df0a1adc16fdab225dc96295e4201d5d72d73e6fc18373e66341d075b42e3a026a819b850a6a3476d52466f
|
7
|
+
data.tar.gz: 247a76932d2cf383f5b3d6767899f2c96e5908f88198b50f041c31bd9cdbce81de49f1da2d3517947c8f348a3a5c56618832f04cd7b467e21653c4acef9f17b7
|
@@ -105,6 +105,60 @@ module Dscf
|
|
105
105
|
end
|
106
106
|
end
|
107
107
|
|
108
|
+
def accept
|
109
|
+
@obj = find_record
|
110
|
+
service = Dscf::Marketplace::DeliveryOrderService.new
|
111
|
+
begin
|
112
|
+
service.assign_driver(@obj, current_user)
|
113
|
+
render_success("delivery_orders.success.accepted", data: @obj)
|
114
|
+
rescue Dscf::Marketplace::DeliveryOrderService::InvalidStatusTransitionError => e
|
115
|
+
render_error("delivery_orders.errors.invalid_status_transition", message: e.message)
|
116
|
+
rescue Dscf::Marketplace::DeliveryOrderService::AssignmentError => e
|
117
|
+
render_error("delivery_orders.errors.assignment_failed", message: e.message)
|
118
|
+
rescue => e
|
119
|
+
render_error("delivery_orders.errors.accept_failed", message: e.message)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def convert_orders
|
124
|
+
order_ids = params[:order_ids]
|
125
|
+
vehicle_type = params[:vehicle_type]
|
126
|
+
pickup_address_id = params[:pickup_address_id]
|
127
|
+
delivery_notes = params[:delivery_notes]
|
128
|
+
|
129
|
+
# Validate required parameters
|
130
|
+
unless order_ids.present? && vehicle_type.present? && pickup_address_id.present?
|
131
|
+
render_error("delivery_orders.errors.convert_orders_missing_params")
|
132
|
+
return
|
133
|
+
end
|
134
|
+
|
135
|
+
# Find orders and pickup address
|
136
|
+
orders = Dscf::Marketplace::Order.where(id: order_ids)
|
137
|
+
pickup_address = Dscf::Core::Address.find_by(id: pickup_address_id)
|
138
|
+
|
139
|
+
unless pickup_address
|
140
|
+
render_error("delivery_orders.errors.pickup_address_not_found")
|
141
|
+
return
|
142
|
+
end
|
143
|
+
|
144
|
+
# Check if all orders exist
|
145
|
+
if orders.count != order_ids.length
|
146
|
+
missing_ids = order_ids - orders.pluck(:id)
|
147
|
+
render_error("delivery_orders.errors.orders_not_found", message: "Orders not found: #{missing_ids.join(", ")}")
|
148
|
+
return
|
149
|
+
end
|
150
|
+
|
151
|
+
service = Dscf::Marketplace::DeliveryOrderService.new
|
152
|
+
begin
|
153
|
+
delivery_order = service.convert_orders_to_delivery(orders, vehicle_type, pickup_address, delivery_notes)
|
154
|
+
render_success("delivery_orders.success.orders_converted", data: delivery_order)
|
155
|
+
rescue Dscf::Marketplace::DeliveryOrderService::ConversionError => e
|
156
|
+
render_error("delivery_orders.errors.orders_conversion_failed", message: e.message)
|
157
|
+
rescue => e
|
158
|
+
render_error("delivery_orders.errors.convert_orders_failed", message: e.message)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
108
162
|
private
|
109
163
|
|
110
164
|
def model_params
|
@@ -3,13 +3,13 @@ module Dscf::Marketplace
|
|
3
3
|
enum :status, {draft: 0, assigned: 1, picked_up: 2, in_transit: 3, delivered: 4, failed: 5}, default: :draft
|
4
4
|
enum :vehicle_type, {motorcycle: 0, car: 1, van: 2, truck: 3}
|
5
5
|
|
6
|
-
belongs_to :driver, class_name: "Dscf::Core::User"
|
6
|
+
belongs_to :driver, class_name: "Dscf::Core::User", optional: true
|
7
7
|
belongs_to :pickup_address, class_name: "Dscf::Core::Address"
|
8
8
|
belongs_to :delivery_vehicle, optional: true
|
9
9
|
has_many :delivery_order_items, dependent: :destroy
|
10
10
|
has_many :marketplace_orders, class_name: "Dscf::Marketplace::Order", dependent: :nullify
|
11
11
|
|
12
|
-
validates :driver_id, presence: true
|
12
|
+
validates :driver_id, presence: true, unless: :draft?
|
13
13
|
validates :pickup_address_id, presence: true
|
14
14
|
validates :status, presence: true
|
15
15
|
validates :vehicle_type, presence: true
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module Dscf::Marketplace
|
2
|
+
class DeliveryOrderService
|
3
|
+
class InvalidStatusTransitionError < StandardError; end
|
4
|
+
|
5
|
+
class AssignmentError < StandardError; end
|
6
|
+
|
7
|
+
class ConversionError < StandardError; end
|
8
|
+
|
9
|
+
def assign_driver(delivery_order, driver)
|
10
|
+
raise ArgumentError, "Delivery order is required" unless delivery_order
|
11
|
+
raise ArgumentError, "Driver is required" unless driver
|
12
|
+
|
13
|
+
unless delivery_order.draft?
|
14
|
+
raise InvalidStatusTransitionError, "Can only assign driver to draft delivery orders"
|
15
|
+
end
|
16
|
+
|
17
|
+
delivery_order.driver_id = driver.id
|
18
|
+
delivery_order.status = :assigned
|
19
|
+
|
20
|
+
unless delivery_order.save
|
21
|
+
raise AssignmentError, "Failed to assign driver: #{delivery_order.errors.full_messages.join(", ")}"
|
22
|
+
end
|
23
|
+
|
24
|
+
delivery_order
|
25
|
+
end
|
26
|
+
|
27
|
+
def convert_orders_to_delivery(orders, vehicle_type, pickup_address, delivery_notes = nil)
|
28
|
+
raise ArgumentError, "Orders array is required" unless orders.present?
|
29
|
+
raise ArgumentError, "Vehicle type is required" unless vehicle_type.present?
|
30
|
+
raise ArgumentError, "Pickup address is required" unless pickup_address.present?
|
31
|
+
|
32
|
+
# Validate all orders can be converted
|
33
|
+
validate_orders_for_conversion(orders)
|
34
|
+
|
35
|
+
# Create delivery order in a transaction
|
36
|
+
DeliveryOrder.transaction do
|
37
|
+
delivery_order = create_delivery_order(vehicle_type, pickup_address, delivery_notes)
|
38
|
+
create_delivery_order_items(delivery_order, orders, pickup_address)
|
39
|
+
associate_orders_with_delivery(delivery_order, orders)
|
40
|
+
|
41
|
+
delivery_order
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def validate_orders_for_conversion(orders)
|
48
|
+
orders.each do |order|
|
49
|
+
unless order.delivery?
|
50
|
+
raise ConversionError, "Order #{order.id} is not a delivery order"
|
51
|
+
end
|
52
|
+
|
53
|
+
unless order.confirmed? || order.processing?
|
54
|
+
raise ConversionError, "Order #{order.id} must be confirmed or processing to be converted"
|
55
|
+
end
|
56
|
+
|
57
|
+
if order.delivery_order.present?
|
58
|
+
raise ConversionError, "Order #{order.id} is already associated with a delivery order"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def create_delivery_order(vehicle_type, pickup_address, delivery_notes)
|
64
|
+
DeliveryOrder.create!(
|
65
|
+
vehicle_type: vehicle_type,
|
66
|
+
pickup_address: pickup_address,
|
67
|
+
delivery_notes: delivery_notes,
|
68
|
+
status: :draft
|
69
|
+
)
|
70
|
+
end
|
71
|
+
|
72
|
+
def create_delivery_order_items(delivery_order, orders, pickup_address)
|
73
|
+
orders.each do |order|
|
74
|
+
order.order_items.each do |order_item|
|
75
|
+
# For now, use the pickup address as both pickup and dropoff
|
76
|
+
# In a real implementation, you'd need to get the buyer's delivery address
|
77
|
+
dropoff_address = pickup_address # Temporary fallback
|
78
|
+
|
79
|
+
DeliveryOrderItem.create!(
|
80
|
+
delivery_order: delivery_order,
|
81
|
+
order_item: order_item,
|
82
|
+
quantity: order_item.quantity,
|
83
|
+
pickup_address: pickup_address,
|
84
|
+
dropoff_address: dropoff_address,
|
85
|
+
status: :pending
|
86
|
+
)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def associate_orders_with_delivery(delivery_order, orders)
|
92
|
+
orders.each do |order|
|
93
|
+
order.update!(delivery_order: delivery_order)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
data/config/locales/en.yml
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
# Pattern: {model_name}.{success|errors}.{action_name} - using plural for controller consistency
|
5
5
|
|
6
6
|
en:
|
7
|
-
|
7
|
+
# Core Models
|
8
8
|
category:
|
9
9
|
success:
|
10
10
|
index: "Categories retrieved successfully"
|
@@ -234,28 +234,28 @@ en:
|
|
234
234
|
update: "Failed to update order item"
|
235
235
|
destroy: "Failed to delete order item"
|
236
236
|
|
237
|
-
|
237
|
+
# Delivery Models
|
238
238
|
delivery_order:
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
239
|
+
success:
|
240
|
+
index: "Delivery orders retrieved successfully"
|
241
|
+
show: "Delivery order details retrieved successfully"
|
242
|
+
create: "Delivery order created successfully"
|
243
|
+
update: "Delivery order updated successfully"
|
244
|
+
destroy: "Delivery order deleted successfully"
|
245
|
+
pickup: "Delivery order picked up successfully"
|
246
|
+
start_delivery: "Delivery started successfully"
|
247
|
+
complete_delivery: "Delivery completed successfully"
|
248
|
+
mark_failed: "Delivery marked as failed"
|
249
|
+
errors:
|
250
|
+
index: "Failed to retrieve delivery orders"
|
251
|
+
show: "Failed to retrieve delivery order details"
|
252
|
+
create: "Failed to create delivery order"
|
253
|
+
update: "Failed to update delivery order"
|
254
|
+
destroy: "Failed to delete delivery order"
|
255
|
+
pickup: "Failed to pickup delivery order"
|
256
|
+
start_delivery: "Failed to start delivery"
|
257
|
+
complete_delivery: "Failed to complete delivery"
|
258
|
+
mark_failed: "Failed to mark delivery as failed"
|
259
259
|
|
260
260
|
delivery_orders:
|
261
261
|
success:
|
@@ -268,7 +268,7 @@ en:
|
|
268
268
|
delivery_started: "Delivery started successfully"
|
269
269
|
delivery_completed: "Delivery completed successfully"
|
270
270
|
marked_failed: "Delivery marked as failed"
|
271
|
-
|
271
|
+
orders_converted: "Orders converted to delivery successfully"
|
272
272
|
errors:
|
273
273
|
index: "Failed to retrieve delivery orders"
|
274
274
|
show: "Failed to retrieve delivery order details"
|
@@ -279,6 +279,15 @@ en:
|
|
279
279
|
delivery_started: "Failed to start delivery"
|
280
280
|
delivery_completed: "Failed to complete delivery"
|
281
281
|
marked_failed: "Failed to mark delivery as failed"
|
282
|
+
pickup_failed: "Failed to pickup delivery order"
|
283
|
+
start_delivery_failed: "Failed to start delivery"
|
284
|
+
complete_delivery_failed: "Failed to complete delivery"
|
285
|
+
mark_failed_failed: "Failed to mark delivery as failed"
|
286
|
+
convert_orders_missing_params: "Missing required parameters: order_ids, vehicle_type, and pickup_address_id"
|
287
|
+
pickup_address_not_found: "Pickup address not found"
|
288
|
+
orders_not_found: "Some orders were not found"
|
289
|
+
orders_conversion_failed: "Failed to convert orders to delivery"
|
290
|
+
convert_orders_failed: "Unexpected error during order conversion"
|
282
291
|
|
283
292
|
delivery_order_item:
|
284
293
|
success:
|
data/config/routes.rb
CHANGED
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.3.
|
4
|
+
version: 0.3.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Asrat
|
@@ -469,6 +469,7 @@ files:
|
|
469
469
|
- app/serializers/dscf/marketplace/unit_conversion_serializer.rb
|
470
470
|
- app/serializers/dscf/marketplace/unit_serializer.rb
|
471
471
|
- app/serializers/dscf/marketplace/user_serializer.rb
|
472
|
+
- app/services/dscf/marketplace/delivery_order_service.rb
|
472
473
|
- app/services/dscf/marketplace/my_resource_service.rb
|
473
474
|
- app/services/dscf/marketplace/rfq_response_service.rb
|
474
475
|
- config/environments/production.rb
|
@@ -499,6 +500,7 @@ files:
|
|
499
500
|
- db/migrate/20250903061154_add_ordered_fields_to_orders.rb
|
500
501
|
- db/migrate/20250903061306_populate_ordered_fields_for_existing_orders.rb
|
501
502
|
- db/migrate/20250909092700_add_notes_to_dscf_marketplace_quotation_items.rb
|
503
|
+
- db/migrate/20250916083536_make_driver_id_nullable_in_delivery_orders.rb
|
502
504
|
- lib/dscf/marketplace.rb
|
503
505
|
- lib/dscf/marketplace/engine.rb
|
504
506
|
- lib/dscf/marketplace/version.rb
|