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 +4 -4
- data/app/models/bscf/core/business_document.rb +40 -0
- data/app/models/bscf/core/marketplace_listing.rb +0 -1
- data/app/models/bscf/core/product.rb +5 -0
- data/app/models/bscf/core/wholesaler_product.rb +36 -0
- data/db/migrate/20250331113323_create_bscf_core_marketplace_listings.rb +2 -2
- data/db/migrate/20250402120554_create_bscf_core_wholesaler_products.rb +14 -0
- data/db/migrate/20250403190620_create_bscf_core_business_documents.rb +14 -0
- data/lib/bscf/core/version.rb +1 -1
- data/spec/factories/bscf/core/business_documents.rb +23 -0
- data/spec/factories/bscf/core/products.rb +22 -2
- data/spec/factories/bscf/core/wholesaler_products.rb +19 -0
- metadata +10 -5
- data/lib/bscf_core.rb +0 -7
- /data/app/services/{token_service.rb → bscf/core/token_service.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: a665cac0e90ed35610f60b90c87ef86eddc49b7b5ea3f89e121fb76ff1273326
|
4
|
+
data.tar.gz: e081ceb0f304fbf2a236d8d9eeb6054c49242dae83a2662aaf524a22324c9cd2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
@@ -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
|
data/lib/bscf/core/version.rb
CHANGED
@@ -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
|
-
|
6
|
-
|
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.
|
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-
|
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/
|
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.
|
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
File without changes
|