bscf-core 0.2.4 → 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: 3cde161c7d4c6d6ccb3959aec98e0d3a573e9bc479aad54047a83292b7153bdb
4
- data.tar.gz: 58b576b12c6baae3ddb9c646f258c62207e28f214a3dbcfb7c5aef400e27f996
3
+ metadata.gz: 75345bb3a5869aba8be1a2a9a71d83634f0361375caa67c050f89132c80a7af7
4
+ data.tar.gz: 609ce23cc23a142163c6a2d12ceaea2de8315512dade8336fc3f7367b1421b9a
5
5
  SHA512:
6
- metadata.gz: ae312fd7b2c3e2a44d91d1c06141d24da26063497263704a32c78b880fa4f6a53cc01999cdfba53823df5f9e88ac4dcd40a5c4deb052e0c4128663952a129409
7
- data.tar.gz: ed20ab86ae39f63bb25bb0d4493d17d67a15e0db36939392f14b324d5eaf716474f2a4f03cd357f3a2ae0d6142ab0c86739882efa1abb4e48279efc23b499c97
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
@@ -0,0 +1,14 @@
1
+ module Bscf
2
+ module Core
3
+ class MarketplaceListing < ApplicationRecord
4
+ belongs_to :user
5
+ belongs_to :address
6
+
7
+ validates :listing_type, :status, :is_active, presence: true
8
+
9
+ enum :listing_type, { buy: 0, sell: 1 }
10
+ enum :status, { open: 0, partially_matched: 1, matched: 2, completed: 3, cancelled: 4 }
11
+
12
+ end
13
+ end
14
+ 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
@@ -0,0 +1,16 @@
1
+ class CreateBscfCoreMarketplaceListings < ActiveRecord::Migration[8.0]
2
+ def change
3
+ create_table :bscf_core_marketplace_listings do |t|
4
+ t.references :user, null: false, foreign_key: {to_table: :bscf_core_users}
5
+ t.integer :listing_type, null: false
6
+ t.integer :status, null: false
7
+ t.boolean :allow_partial_match, null: false, default: false
8
+ t.datetime :preferred_delivery_date
9
+ t.datetime :expires_at
10
+ t.boolean :is_active, default: true
11
+ t.references :address, null: false, foreign_key: {to_table: :bscf_core_addresses}
12
+
13
+ t.timestamps
14
+ end
15
+ end
16
+ end
@@ -1,5 +1,5 @@
1
1
  module Bscf
2
2
  module Core
3
- VERSION = "0.2.4"
3
+ VERSION = "0.3.0"
4
4
  end
5
5
  end
data/lib/bscf/core.rb CHANGED
@@ -1,5 +1,9 @@
1
1
  require "bscf/core/version"
2
2
  require "bscf/core/engine"
3
+ require "jwt"
4
+ require "active_model_serializers"
5
+ require "ancestry"
6
+ require "ransack"
3
7
 
4
8
  module Bscf
5
9
  module Core
@@ -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
@@ -0,0 +1,12 @@
1
+ FactoryBot.define do
2
+ factory :marketplace_listing, class: 'Bscf::Core::MarketplaceListing' do
3
+ user
4
+ listing_type { 1 }
5
+ allow_partial_match { false }
6
+ preferred_delivery_date { DateTime.now.advance(days: 7) }
7
+ expires_at { DateTime.now.advance(days: 5) }
8
+ is_active { true }
9
+ status { 1 }
10
+ address
11
+ end
12
+ 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.4
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Asrat
@@ -290,6 +290,9 @@ 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
295
+ - app/models/bscf/core/marketplace_listing.rb
293
296
  - app/models/bscf/core/order.rb
294
297
  - app/models/bscf/core/order_item.rb
295
298
  - app/models/bscf/core/product.rb
@@ -308,8 +311,8 @@ files:
308
311
  - config/routes.rb
309
312
  - db/migrate/20250326065606_create_bscf_core_users.rb
310
313
  - db/migrate/20250326075111_create_bscf_core_roles.rb
314
+ - db/migrate/20250326080052_create_bscf_core_addresses.rb
311
315
  - db/migrate/20250326080646_create_bscf_core_user_profiles.rb
312
- - db/migrate/20250326081052_create_bscf_core_addresses.rb
313
316
  - db/migrate/20250326084233_create_bscf_core_user_roles.rb
314
317
  - db/migrate/20250326085741_create_bscf_core_virtual_accounts.rb
315
318
  - db/migrate/20250326103305_create_bscf_core_categories.rb
@@ -322,6 +325,9 @@ files:
322
325
  - db/migrate/20250327044020_create_bscf_core_quotation_items.rb
323
326
  - db/migrate/20250327102217_create_bscf_core_orders.rb
324
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
330
+ - db/migrate/20250331113323_create_bscf_core_marketplace_listings.rb
325
331
  - lib/bscf/core.rb
326
332
  - lib/bscf/core/engine.rb
327
333
  - lib/bscf/core/version.rb
@@ -330,6 +336,9 @@ files:
330
336
  - spec/factories/bscf/core/addresses.rb
331
337
  - spec/factories/bscf/core/businesses.rb
332
338
  - spec/factories/bscf/core/categories.rb
339
+ - spec/factories/bscf/core/delivery_order_items.rb
340
+ - spec/factories/bscf/core/delivery_orders.rb
341
+ - spec/factories/bscf/core/marketplace_listings.rb
333
342
  - spec/factories/bscf/core/order_items.rb
334
343
  - spec/factories/bscf/core/orders.rb
335
344
  - spec/factories/bscf/core/products.rb
@@ -364,7 +373,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
364
373
  - !ruby/object:Gem::Version
365
374
  version: '0'
366
375
  requirements: []
367
- rubygems_version: 3.6.5
376
+ rubygems_version: 3.6.2
368
377
  specification_version: 4
369
378
  summary: An Engine for Supply Chain Financing
370
379
  test_files: []