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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 79299c565b95d752a61eb45769bba9294e6a284f1a8476e78a34c583257306cb
4
- data.tar.gz: 82e9ad70c8f0d8484b4537d4a8313511fc2ecda0c77d5007e4550f1be0688a20
3
+ metadata.gz: 75345bb3a5869aba8be1a2a9a71d83634f0361375caa67c050f89132c80a7af7
4
+ data.tar.gz: 609ce23cc23a142163c6a2d12ceaea2de8315512dade8336fc3f7367b1421b9a
5
5
  SHA512:
6
- metadata.gz: c6674ad3f059ef2afaa9befa0b4bb6005475f93a826ddcf4189383a5d8bfbfda87fda04b15833965044d2eeb10485e06fe3e531480de2ccdfc33c7fb9aaf2516
7
- data.tar.gz: 23e05ad117d361ea39fbfbf5626e837921223efe9c7fdf52e3eba8ea4cc289962736a8670ba18da7325a244f70878b3a3bde5d66158166dc6c4ebe631706c0f7
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
@@ -1,5 +1,5 @@
1
1
  module Bscf
2
2
  module Core
3
- VERSION = "0.2.5"
3
+ VERSION = "0.3.0"
4
4
  end
5
5
  end
@@ -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.2.5
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.5
376
+ rubygems_version: 3.6.2
371
377
  specification_version: 4
372
378
  summary: An Engine for Supply Chain Financing
373
379
  test_files: []