bscf-core 0.3.1 → 0.3.2

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: 02ed83b7ec66c52ec79915063727186f0b8a976a29ffc23db1a8da3aa94719cb
4
- data.tar.gz: a9c0bb068c864c59da70fce33bb1e58088b6748bfeabec939fda97c86a6fdadd
3
+ metadata.gz: a665cac0e90ed35610f60b90c87ef86eddc49b7b5ea3f89e121fb76ff1273326
4
+ data.tar.gz: e081ceb0f304fbf2a236d8d9eeb6054c49242dae83a2662aaf524a22324c9cd2
5
5
  SHA512:
6
- metadata.gz: 252d77e24bde7d0944bb27733fba588d64c06d6394bb2230153cce4640479fb80c55a6bd0f9d66d64a174166829ed441cc88a5d0f8600c9522eda5a732e8958d
7
- data.tar.gz: f62401b9132ac9289c6eb040cab41a15439dae36d6a987639fe0e5885fa0ca3d1785e38eca20de93c82c8ce303b79b7edff8f40136f8b755ab81e1830a308351
6
+ metadata.gz: 88dcb3b6eb964e482640b2bbc490f4d91273daa4bca3ecc64ba5f9a030eb24dc380b2b1721c2f6d6b5c8b0b2dbefe63872452e78d184e819f68f06e40d8a7261
7
+ data.tar.gz: 4f7c894f2338827e3b1b6e1b9cdcf60f67e41239e99ad0308f334dabab3e5bda881e1bf52102b30dd11d88cfd0f8a985c05b80c13b8d3f113fe195c258bcf4a9
@@ -0,0 +1,40 @@
1
+ module Bscf
2
+ module Core
3
+ class BusinessDocument < ApplicationRecord
4
+ belongs_to :business
5
+ has_one_attached :file
6
+
7
+ before_validation :format_document_name
8
+
9
+ validates :document_number, presence: true
10
+ validates :document_name, presence: true
11
+ validates :business_id, presence: true
12
+ validates :verified_at, presence: true, if: :is_verified?
13
+ validates :file, presence: true
14
+ validate :block_executable_files
15
+
16
+ scope :verified, -> { where(is_verified: true) }
17
+ scope :unverified, -> { where(is_verified: false) }
18
+
19
+ private
20
+
21
+ def format_document_name
22
+ self.document_name = document_name.strip.titleize if document_name.present?
23
+ end
24
+
25
+ def block_executable_files
26
+ return unless file.attached?
27
+
28
+ if file.content_type.in?(%w[
29
+ application/x-msdownload
30
+ application/x-executable
31
+ application/x-msdos-program
32
+ application/x-ms-dos-executable
33
+ application/x-shellscript
34
+ ])
35
+ errors.add(:file, "cannot be an executable file")
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -8,7 +8,6 @@ module Bscf
8
8
 
9
9
  enum :listing_type, { buy: 0, sell: 1 }
10
10
  enum :status, { open: 0, partially_matched: 1, matched: 2, completed: 3, cancelled: 4 }
11
-
12
11
  end
13
12
  end
14
13
  end
@@ -2,7 +2,12 @@ module Bscf
2
2
  module Core
3
3
  class Product < ApplicationRecord
4
4
  belongs_to :category
5
+ has_one_attached :thumbnail
6
+ has_many_attached :images
5
7
 
8
+ validates :sku, presence: true, uniqueness: true
9
+ validates :name, presence: true
10
+ validates :description, presence: true
6
11
  has_many :rfq_items
7
12
  has_many :request_for_quotations, through: :rfq_items
8
13
 
@@ -0,0 +1,36 @@
1
+ module Bscf::Core
2
+ class WholesalerProduct < ApplicationRecord
3
+ belongs_to :business
4
+ belongs_to :product
5
+
6
+ validates :minimum_order_quantity, presence: true, numericality: { greater_than: 0 }
7
+ validates :wholesale_price, presence: true, numericality: { greater_than: 0 }
8
+ validates :available_quantity, presence: true, numericality: { greater_than_or_equal_to: 0 }
9
+ validates :status, presence: true
10
+
11
+ validate :business_must_be_wholesaler
12
+ validate :unique_product_per_wholesaler
13
+
14
+ enum :status, {
15
+ active: 0,
16
+ inactive: 1,
17
+ out_of_stock: 2
18
+ }
19
+
20
+ private
21
+
22
+ def business_must_be_wholesaler
23
+ if business && !business.wholesaler?
24
+ errors.add(:business, "must be a wholesaler")
25
+ end
26
+ end
27
+
28
+ def unique_product_per_wholesaler
29
+ if WholesalerProduct.where(business: business, product: product)
30
+ .where.not(id: id)
31
+ .exists?
32
+ errors.add(:product, "already exists for this wholesaler")
33
+ end
34
+ end
35
+ end
36
+ end
@@ -1,14 +1,14 @@
1
1
  class CreateBscfCoreMarketplaceListings < ActiveRecord::Migration[8.0]
2
2
  def change
3
3
  create_table :bscf_core_marketplace_listings do |t|
4
- t.references :user, null: false, foreign_key: {to_table: :bscf_core_users}
4
+ t.references :user, null: false, foreign_key: { to_table: :bscf_core_users }
5
5
  t.integer :listing_type, null: false
6
6
  t.integer :status, null: false
7
7
  t.boolean :allow_partial_match, null: false, default: false
8
8
  t.datetime :preferred_delivery_date
9
9
  t.datetime :expires_at
10
10
  t.boolean :is_active, default: true
11
- t.references :address, null: false, foreign_key: {to_table: :bscf_core_addresses}
11
+ t.references :address, null: false, foreign_key: { to_table: :bscf_core_addresses }
12
12
 
13
13
  t.timestamps
14
14
  end
@@ -0,0 +1,14 @@
1
+ class CreateBscfCoreWholesalerProducts < ActiveRecord::Migration[8.0]
2
+ def change
3
+ create_table :bscf_core_wholesaler_products do |t|
4
+ t.references :business, null: false, foreign_key: { to_table: :bscf_core_businesses }
5
+ t.references :product, null: false, foreign_key: { to_table: :bscf_core_products }
6
+ t.integer :minimum_order_quantity, null: false, default: 1
7
+ t.decimal :wholesale_price
8
+ t.integer :available_quantity, null: false, default: 0
9
+ t.integer :status, null: false, default: 0
10
+
11
+ t.timestamps
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ class CreateBscfCoreBusinessDocuments < ActiveRecord::Migration[8.0]
2
+ def change
3
+ create_table :bscf_core_business_documents do |t|
4
+ t.references :business, null: false, foreign_key: { to_table: :bscf_core_businesses }
5
+ t.string :document_number, null: false
6
+ t.string :document_name, null: false
7
+ t.string :document_description
8
+ t.datetime :verified_at
9
+ t.boolean :is_verified, null: false, default: false
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.3.1"
3
+ VERSION = "0.3.2"
4
4
  end
5
5
  end
@@ -0,0 +1,23 @@
1
+ FactoryBot.define do
2
+ factory :business_document, class: 'Bscf::Core::BusinessDocument' do
3
+ association :business, factory: :business
4
+ document_number { "DOC-#{SecureRandom.hex(4).upcase}" }
5
+ document_name { "Business License" }
6
+ document_description { "Official business license document" }
7
+ is_verified { false }
8
+
9
+ after(:build) do |document|
10
+ document.file.attach(
11
+ io: StringIO.new("test content"),
12
+ filename: 'sample.pdf',
13
+ content_type: 'application/pdf'
14
+ )
15
+ end
16
+
17
+ trait :verified do
18
+ is_verified { true }
19
+ verified_at { Time.current }
20
+ association :business, factory: :business
21
+ end
22
+ end
23
+ end
@@ -1,8 +1,28 @@
1
1
  FactoryBot.define do
2
2
  factory :product, class: 'Bscf::Core::Product' do
3
+ category
4
+ sequence(:sku) { |n| "SKU-#{n}" }
3
5
  name { Faker::Commerce.product_name }
4
6
  description { Faker::Lorem.paragraph }
5
- association :category, factory: :category
6
- base_price { Faker::Commerce.price(range: 0..1000.0) }
7
+
8
+ after(:build) do |product|
9
+ product.thumbnail.attach(
10
+ io: StringIO.new("test image"),
11
+ filename: 'thumbnail.jpg',
12
+ content_type: 'image/jpeg'
13
+ )
14
+ end
15
+
16
+ trait :with_images do
17
+ after(:build) do |product|
18
+ 2.times do |i|
19
+ product.images.attach(
20
+ io: StringIO.new("test image #{i}"),
21
+ filename: "image_#{i}.jpg",
22
+ content_type: 'image/jpeg'
23
+ )
24
+ end
25
+ end
26
+ end
7
27
  end
8
28
  end
@@ -0,0 +1,19 @@
1
+ FactoryBot.define do
2
+ factory :wholesaler_product, class: 'Bscf::Core::WholesalerProduct' do
3
+ association :business, :wholesaler
4
+ association :product
5
+ minimum_order_quantity { Faker::Number.between(from: 5, to: 100) }
6
+ wholesale_price { Faker::Commerce.price(range: 50..1000.0) }
7
+ available_quantity { Faker::Number.between(from: 100, to: 1000) }
8
+ status { :active }
9
+ end
10
+
11
+ trait :inactive do
12
+ status { :inactive }
13
+ end
14
+
15
+ trait :out_of_stock do
16
+ status { :out_of_stock }
17
+ available_quantity { 0 }
18
+ end
19
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bscf-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Asrat
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-04-01 00:00:00.000000000 Z
10
+ date: 2025-04-04 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: active_model_serializers
@@ -289,6 +289,7 @@ files:
289
289
  - app/models/bscf/core/address.rb
290
290
  - app/models/bscf/core/application_record.rb
291
291
  - app/models/bscf/core/business.rb
292
+ - app/models/bscf/core/business_document.rb
292
293
  - app/models/bscf/core/category.rb
293
294
  - app/models/bscf/core/delivery_order.rb
294
295
  - app/models/bscf/core/delivery_order_item.rb
@@ -306,7 +307,8 @@ files:
306
307
  - app/models/bscf/core/user_role.rb
307
308
  - app/models/bscf/core/virtual_account.rb
308
309
  - app/models/bscf/core/virtual_account_transaction.rb
309
- - app/services/token_service.rb
310
+ - app/models/bscf/core/wholesaler_product.rb
311
+ - app/services/bscf/core/token_service.rb
310
312
  - config/database.yml
311
313
  - config/routes.rb
312
314
  - db/migrate/20250326065606_create_bscf_core_users.rb
@@ -328,13 +330,15 @@ files:
328
330
  - db/migrate/20250330181143_create_bscf_core_delivery_orders.rb
329
331
  - db/migrate/20250330190145_create_bscf_core_delivery_order_items.rb
330
332
  - db/migrate/20250331113323_create_bscf_core_marketplace_listings.rb
333
+ - db/migrate/20250402120554_create_bscf_core_wholesaler_products.rb
334
+ - db/migrate/20250403190620_create_bscf_core_business_documents.rb
331
335
  - lib/bscf/core.rb
332
336
  - lib/bscf/core/engine.rb
333
337
  - lib/bscf/core/version.rb
334
- - lib/bscf_core.rb
335
338
  - lib/tasks/bscf/core_tasks.rake
336
339
  - lib/tasks/release.rake
337
340
  - spec/factories/bscf/core/addresses.rb
341
+ - spec/factories/bscf/core/business_documents.rb
338
342
  - spec/factories/bscf/core/businesses.rb
339
343
  - spec/factories/bscf/core/categories.rb
340
344
  - spec/factories/bscf/core/delivery_order_items.rb
@@ -353,6 +357,7 @@ files:
353
357
  - spec/factories/bscf/core/users.rb
354
358
  - spec/factories/bscf/core/virtual_account_transactions.rb
355
359
  - spec/factories/bscf/core/virtual_accounts.rb
360
+ - spec/factories/bscf/core/wholesaler_products.rb
356
361
  homepage: https://mksaddis.com/
357
362
  licenses:
358
363
  - MIT
@@ -374,7 +379,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
374
379
  - !ruby/object:Gem::Version
375
380
  version: '0'
376
381
  requirements: []
377
- rubygems_version: 3.6.5
382
+ rubygems_version: 3.6.2
378
383
  specification_version: 4
379
384
  summary: An Engine for Supply Chain Financing
380
385
  test_files: []
data/lib/bscf_core.rb DELETED
@@ -1,7 +0,0 @@
1
- require "bscf/core/version"
2
- require "bscf/core/engine"
3
- require "active_model_serializers"
4
- require "ancestry"
5
- require "jwt"
6
- require "ransack"
7
- require "noticed"