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 +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/marketplace_listing.rb +14 -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/db/migrate/20250331113323_create_bscf_core_marketplace_listings.rb +16 -0
- data/lib/bscf/core/version.rb +1 -1
- data/lib/bscf/core.rb +4 -0
- data/spec/factories/bscf/core/delivery_order_items.rb +10 -0
- data/spec/factories/bscf/core/delivery_orders.rb +11 -0
- data/spec/factories/bscf/core/marketplace_listings.rb +12 -0
- metadata +12 -3
- /data/db/migrate/{20250326081052_create_bscf_core_addresses.rb → 20250326080052_create_bscf_core_addresses.rb} +0 -0
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
|
@@ -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
|
data/lib/bscf/core/version.rb
CHANGED
data/lib/bscf/core.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
|
@@ -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.
|
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.
|
376
|
+
rubygems_version: 3.6.2
|
368
377
|
specification_version: 4
|
369
378
|
summary: An Engine for Supply Chain Financing
|
370
379
|
test_files: []
|
File without changes
|