bscf-core 0.2.5 → 0.3.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/models/bscf/core/delivery_order.rb +61 -0
- data/app/models/bscf/core/delivery_order_item.rb +51 -0
- data/app/models/bscf/core/order.rb +1 -1
- data/db/migrate/20250330181143_create_bscf_core_delivery_orders.rb +16 -0
- data/db/migrate/20250330190145_create_bscf_core_delivery_order_items.rb +14 -0
- data/lib/bscf/core/version.rb +1 -1
- data/spec/factories/bscf/core/delivery_order_items.rb +10 -0
- data/spec/factories/bscf/core/delivery_orders.rb +11 -0
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 75345bb3a5869aba8be1a2a9a71d83634f0361375caa67c050f89132c80a7af7
|
4
|
+
data.tar.gz: 609ce23cc23a142163c6a2d12ceaea2de8315512dade8336fc3f7367b1421b9a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: de59cc788cb76d57b82f19dd4628dbbd5dd4960d66fe80127a65cfe86104b3b574e7d1c348add0b4f09b31bdf27d77ff75756dde916128e02452071c2acd55a6
|
7
|
+
data.tar.gz: 339827dcdfed5cf99bf8e3f5f168a423f346f493ca1b0f5762df80a66a05b5441f5244da11142bb23e07ef331d0151c1cca78ae2c131619b7233c691da92d807
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Bscf::Core
|
2
|
+
class DeliveryOrder < ApplicationRecord
|
3
|
+
belongs_to :order
|
4
|
+
belongs_to :delivery_address, class_name: "Bscf::Core::Address"
|
5
|
+
|
6
|
+
has_many :delivery_order_items, dependent: :destroy
|
7
|
+
has_many :order_items, through: :delivery_order_items
|
8
|
+
has_many :products, through: :delivery_order_items
|
9
|
+
|
10
|
+
attribute :delivery_start_time, :datetime
|
11
|
+
attribute :delivery_end_time, :datetime
|
12
|
+
attribute :actual_delivery_time, :datetime
|
13
|
+
|
14
|
+
validates :contact_phone, :status, :estimated_delivery_time, presence: true
|
15
|
+
validate :end_time_after_start_time, if: -> { delivery_start_time.present? && delivery_end_time.present? }
|
16
|
+
|
17
|
+
before_save :update_delivery_times
|
18
|
+
before_save :calculate_actual_delivery_time
|
19
|
+
|
20
|
+
after_save :sync_items_status, if: :saved_change_to_status?
|
21
|
+
|
22
|
+
enum :status, {
|
23
|
+
pending: 0,
|
24
|
+
in_transit: 1,
|
25
|
+
delivered: 2,
|
26
|
+
failed: 3,
|
27
|
+
cancelled: 4
|
28
|
+
}
|
29
|
+
|
30
|
+
def delivery_duration
|
31
|
+
return nil unless delivery_start_time && delivery_end_time
|
32
|
+
((delivery_end_time - delivery_start_time) / 1.hour).round(2)
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def update_delivery_times
|
38
|
+
case status
|
39
|
+
when "in_transit"
|
40
|
+
self.delivery_start_time = Time.current if delivery_start_time.nil?
|
41
|
+
when "delivered", "failed"
|
42
|
+
self.delivery_end_time = Time.current if delivery_end_time.nil?
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def calculate_actual_delivery_time
|
47
|
+
self.actual_delivery_time = delivery_end_time if status == "delivered"
|
48
|
+
end
|
49
|
+
|
50
|
+
def end_time_after_start_time
|
51
|
+
return unless delivery_start_time && delivery_end_time
|
52
|
+
if delivery_end_time <= delivery_start_time
|
53
|
+
errors.add(:delivery_end_time, "must be after delivery start time")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def sync_items_status
|
58
|
+
delivery_order_items.update_all(status: status)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Bscf::Core
|
2
|
+
class DeliveryOrderItem < ApplicationRecord
|
3
|
+
belongs_to :delivery_order
|
4
|
+
belongs_to :order_item
|
5
|
+
belongs_to :product
|
6
|
+
|
7
|
+
validates :quantity, :status, presence: true
|
8
|
+
validate :quantity_not_exceeding_order_item
|
9
|
+
validate :status_matches_delivery_order
|
10
|
+
|
11
|
+
after_save :update_delivery_order_status
|
12
|
+
before_save :sync_status_with_delivery_order
|
13
|
+
|
14
|
+
enum :status, {
|
15
|
+
pending: 0,
|
16
|
+
in_transit: 1,
|
17
|
+
delivered: 2,
|
18
|
+
failed: 3,
|
19
|
+
cancelled: 4
|
20
|
+
}
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def quantity_not_exceeding_order_item
|
25
|
+
return unless quantity && order_item&.quantity
|
26
|
+
if quantity > order_item.quantity
|
27
|
+
errors.add(:quantity, "cannot exceed order item quantity (#{order_item.quantity.to_i})")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def status_matches_delivery_order
|
32
|
+
return unless delivery_order && status_changed?
|
33
|
+
unless status.to_s == delivery_order.status
|
34
|
+
errors.add(:status, "must match delivery order status")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def sync_status_with_delivery_order
|
39
|
+
self.status = delivery_order.status if delivery_order
|
40
|
+
end
|
41
|
+
|
42
|
+
def update_delivery_order_status
|
43
|
+
return unless status_previously_changed?
|
44
|
+
|
45
|
+
all_items_status = delivery_order.delivery_order_items.pluck(:status).uniq
|
46
|
+
if all_items_status.size == 1
|
47
|
+
delivery_order.update(status: all_items_status.first)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -4,7 +4,7 @@ module Bscf
|
|
4
4
|
belongs_to :ordered_by, class_name: "Bscf::Core::User", optional: true
|
5
5
|
belongs_to :ordered_to, class_name: "Bscf::Core::User", optional: true
|
6
6
|
belongs_to :quotation, optional: true
|
7
|
-
|
7
|
+
has_many :order_items, dependent: :destroy
|
8
8
|
validates :order_type, :status, presence: true
|
9
9
|
|
10
10
|
enum :order_type, {
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class CreateBscfCoreDeliveryOrders < ActiveRecord::Migration[8.0]
|
2
|
+
def change
|
3
|
+
create_table :bscf_core_delivery_orders do |t|
|
4
|
+
t.references :order, null: false, foreign_key: { to_table: :bscf_core_orders, on_delete: :cascade, on_update: :cascade }
|
5
|
+
t.references :delivery_address, null: false, foreign_key: { to_table: :bscf_core_addresses }
|
6
|
+
t.string :contact_phone, null: false
|
7
|
+
t.text :delivery_notes
|
8
|
+
t.datetime :estimated_delivery_time, null: false
|
9
|
+
t.datetime :delivery_start_time
|
10
|
+
t.datetime :delivery_end_time
|
11
|
+
t.integer :status, null: false, default: 0
|
12
|
+
|
13
|
+
t.timestamps
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class CreateBscfCoreDeliveryOrderItems < ActiveRecord::Migration[8.0]
|
2
|
+
def change
|
3
|
+
create_table :bscf_core_delivery_order_items do |t|
|
4
|
+
t.references :delivery_order, null: false, foreign_key: { to_table: :bscf_core_delivery_orders }
|
5
|
+
t.references :order_item, null: false, foreign_key: { to_table: :bscf_core_order_items }
|
6
|
+
t.references :product, null: false, foreign_key: { to_table: :bscf_core_products }
|
7
|
+
t.integer :quantity, null: false
|
8
|
+
t.integer :status, null: false, default: 0
|
9
|
+
t.text :notes
|
10
|
+
|
11
|
+
t.timestamps
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/bscf/core/version.rb
CHANGED
@@ -0,0 +1,10 @@
|
|
1
|
+
FactoryBot.define do
|
2
|
+
factory :delivery_order_item, class: 'Bscf::Core::DeliveryOrderItem' do
|
3
|
+
association :delivery_order
|
4
|
+
association :order_item
|
5
|
+
association :product
|
6
|
+
quantity { order_item.quantity }
|
7
|
+
status { :pending }
|
8
|
+
notes { Faker::Lorem.paragraph }
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
FactoryBot.define do
|
2
|
+
factory :delivery_order, class: 'Bscf::Core::DeliveryOrder' do
|
3
|
+
association :order
|
4
|
+
association :delivery_address, factory: :address
|
5
|
+
contact_phone { Faker::PhoneNumber.phone_number }
|
6
|
+
delivery_notes { Faker::Lorem.paragraph }
|
7
|
+
estimated_delivery_time { 2.days.from_now }
|
8
|
+
actual_delivery_time { nil }
|
9
|
+
status { :pending }
|
10
|
+
end
|
11
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bscf-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Asrat
|
@@ -290,6 +290,8 @@ files:
|
|
290
290
|
- app/models/bscf/core/application_record.rb
|
291
291
|
- app/models/bscf/core/business.rb
|
292
292
|
- app/models/bscf/core/category.rb
|
293
|
+
- app/models/bscf/core/delivery_order.rb
|
294
|
+
- app/models/bscf/core/delivery_order_item.rb
|
293
295
|
- app/models/bscf/core/marketplace_listing.rb
|
294
296
|
- app/models/bscf/core/order.rb
|
295
297
|
- app/models/bscf/core/order_item.rb
|
@@ -323,6 +325,8 @@ files:
|
|
323
325
|
- db/migrate/20250327044020_create_bscf_core_quotation_items.rb
|
324
326
|
- db/migrate/20250327102217_create_bscf_core_orders.rb
|
325
327
|
- db/migrate/20250327112412_create_bscf_core_order_items.rb
|
328
|
+
- db/migrate/20250330181143_create_bscf_core_delivery_orders.rb
|
329
|
+
- db/migrate/20250330190145_create_bscf_core_delivery_order_items.rb
|
326
330
|
- db/migrate/20250331113323_create_bscf_core_marketplace_listings.rb
|
327
331
|
- lib/bscf/core.rb
|
328
332
|
- lib/bscf/core/engine.rb
|
@@ -332,6 +336,8 @@ files:
|
|
332
336
|
- spec/factories/bscf/core/addresses.rb
|
333
337
|
- spec/factories/bscf/core/businesses.rb
|
334
338
|
- spec/factories/bscf/core/categories.rb
|
339
|
+
- spec/factories/bscf/core/delivery_order_items.rb
|
340
|
+
- spec/factories/bscf/core/delivery_orders.rb
|
335
341
|
- spec/factories/bscf/core/marketplace_listings.rb
|
336
342
|
- spec/factories/bscf/core/order_items.rb
|
337
343
|
- spec/factories/bscf/core/orders.rb
|
@@ -367,7 +373,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
367
373
|
- !ruby/object:Gem::Version
|
368
374
|
version: '0'
|
369
375
|
requirements: []
|
370
|
-
rubygems_version: 3.6.
|
376
|
+
rubygems_version: 3.6.2
|
371
377
|
specification_version: 4
|
372
378
|
summary: An Engine for Supply Chain Financing
|
373
379
|
test_files: []
|