dscf-marketplace 0.3.93 → 0.3.95
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 +52 -0
- data/app/models/dscf/marketplace/quotation.rb +15 -1
- data/app/models/dscf/marketplace/quotation_item.rb +6 -0
- data/app/services/dscf/marketplace/delivery_order_service.rb +2 -1
- data/app/services/dscf/marketplace/rfq_response_service.rb +1 -0
- data/config/locales/en.yml +1 -0
- data/config/routes.rb +1 -0
- data/db/migrate/20250920105329_backfill_quotation_total_prices.rb +11 -0
- data/lib/dscf/marketplace/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5878fba3426fc915f242010ea6bdb33c005c9ef025b024927bae599c507bfe03
|
4
|
+
data.tar.gz: 7088299b3f36bb604631e8613d08abf6e36bbc333654e353d024ea3963f1733c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 02ab38c3146642161812dbcb3b9de94d748af96ada56bf9d159eb183659b8f5c50eb1223d484d5219a2b98327f86ff4b107e817cf856b1904d5dd72db76536ca
|
7
|
+
data.tar.gz: 9b3815919000c5f5b57cf93ffd3bd1af6f165efcf1ff4ab1debedc9efb3e36a6c4ca0fffcbe58aea16fb0236c21d104b328d506178b6bdcb7480d399d07e15a2
|
@@ -159,8 +159,60 @@ module Dscf
|
|
159
159
|
end
|
160
160
|
end
|
161
161
|
|
162
|
+
def my_driver_deliveries
|
163
|
+
# Verify user has driver role
|
164
|
+
unless Dscf::Marketplace::RoleService.user_has_driver_role?(current_user)
|
165
|
+
render_error("delivery_orders.errors.access_denied", message: "Only drivers can access this endpoint")
|
166
|
+
return
|
167
|
+
end
|
168
|
+
|
169
|
+
# Get deliveries where user is the driver
|
170
|
+
delivery_orders = @clazz.where(driver: current_user)
|
171
|
+
|
172
|
+
# Apply Ransack filtering if q params present
|
173
|
+
if params[:q].present?
|
174
|
+
# Filter out any parameters that might reference JSON fields
|
175
|
+
filtered_params = params[:q].reject { |key, _| key.to_s.include?("optimized_route") }
|
176
|
+
if filtered_params.present?
|
177
|
+
delivery_orders = delivery_orders.ransack(filtered_params).result
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
# Apply eager loading if defined
|
182
|
+
delivery_orders = delivery_orders.includes(eager_loaded_associations) if eager_loaded_associations.present?
|
183
|
+
|
184
|
+
# Apply pagination if requested
|
185
|
+
if params[:page]
|
186
|
+
total_count = delivery_orders.count
|
187
|
+
delivery_orders = delivery_orders.then(&paginate)
|
188
|
+
total_pages = (total_count.to_f / per_page).ceil
|
189
|
+
count = delivery_orders.is_a?(Array) ? delivery_orders.length : delivery_orders.count
|
190
|
+
|
191
|
+
pagination_meta = {
|
192
|
+
current_page: page_no,
|
193
|
+
per_page: per_page,
|
194
|
+
count: count,
|
195
|
+
total_count: total_count,
|
196
|
+
total_pages: total_pages,
|
197
|
+
links: pagination_links(total_pages)
|
198
|
+
}
|
199
|
+
end
|
200
|
+
|
201
|
+
# Add serializer includes
|
202
|
+
includes = serializer_includes_for_action(:index)
|
203
|
+
options = {}
|
204
|
+
options[:include] = includes if includes.present?
|
205
|
+
options[:pagination] = pagination_meta if params[:page]
|
206
|
+
|
207
|
+
render_success(data: delivery_orders, serializer_options: options)
|
208
|
+
end
|
209
|
+
|
162
210
|
private
|
163
211
|
|
212
|
+
def find_record
|
213
|
+
Dscf::Marketplace::DeliveryOrder.find(params[:id])
|
214
|
+
end
|
215
|
+
|
164
216
|
def model_params
|
165
217
|
params.require(:delivery_order).permit(
|
166
218
|
:driver_id, :pickup_address_id, :delivery_vehicle_id, :status,
|
@@ -19,6 +19,7 @@ module Dscf
|
|
19
19
|
validate :valid_until_after_delivery_date
|
20
20
|
validate :delivery_date_not_in_past
|
21
21
|
validate :valid_until_not_in_past
|
22
|
+
validate :total_price_required_for_operations
|
22
23
|
scope :by_business, ->(business_id) { where(business_id: business_id) }
|
23
24
|
scope :valid_quotations, -> { where("valid_until > ?", Time.current) }
|
24
25
|
scope :expired_quotations, -> { where("valid_until <= ?", Time.current) }
|
@@ -170,7 +171,9 @@ module Dscf
|
|
170
171
|
private
|
171
172
|
|
172
173
|
def calculate_total_price
|
173
|
-
|
174
|
+
# Reload association to ensure we have the latest data
|
175
|
+
quotation_items.reload
|
176
|
+
self.total_price = quotation_items.sum { |item| item.subtotal || 0 }.to_f
|
174
177
|
end
|
175
178
|
|
176
179
|
def valid_until_after_delivery_date
|
@@ -196,6 +199,17 @@ module Dscf
|
|
196
199
|
errors.add(:valid_until, "cannot be in the past")
|
197
200
|
end
|
198
201
|
end
|
202
|
+
|
203
|
+
def total_price_required_for_operations
|
204
|
+
return if total_price.present?
|
205
|
+
return if draft? # Allow null total_price for draft quotations
|
206
|
+
return if quotation_items.empty? # Allow null if no items
|
207
|
+
|
208
|
+
# Require total_price for sent, accepted, rejected, or expired quotations
|
209
|
+
if sent? || accepted? || rejected? || expired?
|
210
|
+
errors.add(:total_price, "must be calculated before quotation can be processed")
|
211
|
+
end
|
212
|
+
end
|
199
213
|
end
|
200
214
|
end
|
201
215
|
end
|
@@ -15,6 +15,8 @@ module Dscf
|
|
15
15
|
# validate :unit_compatible_with_product
|
16
16
|
validate :subtotal_matches_calculation, if: :should_validate_subtotal?
|
17
17
|
before_save :calculate_subtotal, if: :should_recalculate_subtotal?
|
18
|
+
after_save :update_quotation_total_price
|
19
|
+
after_destroy :update_quotation_total_price
|
18
20
|
|
19
21
|
scope :priced, -> { where.not(unit_price: nil) }
|
20
22
|
scope :unpriced, -> { where(unit_price: nil) }
|
@@ -86,6 +88,10 @@ module Dscf
|
|
86
88
|
self.subtotal = (unit_price * quantity).round(2)
|
87
89
|
end
|
88
90
|
|
91
|
+
def update_quotation_total_price
|
92
|
+
quotation.update_total_price! if quotation.present?
|
93
|
+
end
|
94
|
+
|
89
95
|
# Calculate subtotal automatically if not set
|
90
96
|
def calculated_subtotal
|
91
97
|
return subtotal if subtotal.present?
|
@@ -89,7 +89,8 @@ module Dscf::Marketplace
|
|
89
89
|
|
90
90
|
def associate_orders_with_delivery(delivery_order, orders)
|
91
91
|
orders.each do |order|
|
92
|
-
order.update!(delivery_order: delivery_order)
|
92
|
+
order.update!(delivery_order: delivery_order, status: :confirmed)
|
93
|
+
order.order_items.update_all(status: OrderItem.statuses[:confirmed])
|
93
94
|
end
|
94
95
|
end
|
95
96
|
end
|
data/config/locales/en.yml
CHANGED
@@ -288,6 +288,7 @@ en:
|
|
288
288
|
orders_not_found: "Some orders were not found"
|
289
289
|
orders_conversion_failed: "Failed to convert orders to delivery"
|
290
290
|
convert_orders_failed: "Unexpected error during order conversion"
|
291
|
+
access_denied: "Access denied"
|
291
292
|
|
292
293
|
delivery_order_item:
|
293
294
|
success:
|
data/config/routes.rb
CHANGED
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.3.
|
4
|
+
version: 0.3.95
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Asrat
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-09-
|
10
|
+
date: 2025-09-20 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: rails
|
@@ -503,6 +503,7 @@ files:
|
|
503
503
|
- db/migrate/20250909092700_add_notes_to_dscf_marketplace_quotation_items.rb
|
504
504
|
- db/migrate/20250916083536_make_driver_id_nullable_in_delivery_orders.rb
|
505
505
|
- db/migrate/20250917110618_add_dropoff_address_to_dscf_marketplace_orders.rb
|
506
|
+
- db/migrate/20250920105329_backfill_quotation_total_prices.rb
|
506
507
|
- lib/dscf/marketplace.rb
|
507
508
|
- lib/dscf/marketplace/engine.rb
|
508
509
|
- lib/dscf/marketplace/version.rb
|