e-commerce_shop 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: bfcfc6dce34a2d0391f5fe5a61f51bbdb3feb53db94f5e1ed0553558060f8c55
4
+ data.tar.gz: d14e3a9a31ecfcf4e8a12a743c3da8949b1117c6b01a6a35f4f93e1fdd795f27
5
+ SHA512:
6
+ metadata.gz: '08d822113ea118b9fb44e4e34b9a54f9b851ec554631fc2fe98591fbf2877f1597995db00a10d151a67f34888d5526ec69b42f1d1dc948fc1c6881038c3d5dc6'
7
+ data.tar.gz: eb0cc348671298af429aab074fb78801abad6e99e69627372b799664479f1ed8c286de1d841dbfda58b78f3d2a04c6a1487a8005b334633ee957ba619f37cb90
@@ -0,0 +1,36 @@
1
+ require 'rails/generators'
2
+ require 'rails/generators/migration'
3
+
4
+ module Shop
5
+ module Generators
6
+ class InstallGenerator < Rails::Generators::Base
7
+ include Rails::Generators::Migration
8
+ source_root File.expand_path("templates", __dir__)
9
+
10
+ def copy_migration
11
+ migration_template "create_carts.rb", "db/migrate/create_carts.rb"
12
+ migration_template "create_products.rb", "db/migrate/create_products.rb"
13
+ migration_template "create_variants.rb", "db/migrate/create_variants.rb"
14
+ migration_template "create_sizes.rb", "db/migrate/create_sizes.rb"
15
+ migration_template "create_cart_items.rb", "db/migrate/create_cart_items.rb"
16
+ end
17
+
18
+ def copy_models
19
+ template 'cart.rb', 'app/models/cart.rb'
20
+ template 'cart_item.rb', 'app/models/cart_item.rb'
21
+ template 'product.rb', 'app/models/product.rb'
22
+ template 'variant.rb', 'app/models/variant.rb'
23
+ template 'size.rb', 'app/models/size.rb'
24
+ end
25
+
26
+ def self.next_migration_number(path)
27
+ if @prev_migration_nr
28
+ @prev_migration_nr += 1
29
+ else
30
+ @prev_migration_nr = Time.now.utc.strftime("%Y%m%d%H%M%S").to_i
31
+ end
32
+ @prev_migration_nr.to_s
33
+ end
34
+ end
35
+ end
36
+ end
data/lib/shop/cart.rb ADDED
@@ -0,0 +1,42 @@
1
+ module Shop
2
+ class Cart
3
+ attr_reader :user_id
4
+
5
+ def initialize(user_id)
6
+ @user_id = user_id
7
+ @cart = ::Cart.find_by(user_id: @user_id)
8
+ end
9
+
10
+ # Get Cart For User
11
+ def specific_user_cart
12
+ cart = ::Cart.where(user_id: @user_id)
13
+ if cart.present?
14
+ { message: 'Cart Found Successfully', cart: cart, status: :found }
15
+ else
16
+ { message: 'No Cart Found For This User', cart: nil, status: :not_found }
17
+ end
18
+ end
19
+
20
+ # Create Cart
21
+ def create
22
+ @cart = ::Cart.find_or_initialize_by(user_id: @user_id)
23
+ return { message: @cart.errors.full_messages, cart: nil, status: :unprocessable_entity } unless @cart.save
24
+
25
+ { message: 'Cart Created Successfully', cart: @cart, status: :created }
26
+ end
27
+
28
+ # Delete Cart
29
+ def delete
30
+ return { message: @cart.errors.full_messages, cart: @cart, status: :unprocessable_entity } unless @cart.destroy
31
+
32
+ { message: 'Cart Deleted Successfully', cart: nil, status: :deleted }
33
+ end
34
+
35
+ # Clear Cart
36
+ def clear
37
+ return { message: "Items Can't be destroyed", cart: @cart, status: :unprocessable_entity } unless @cart.cart_items.destroy_all && @cart.update(total_amount: 0.0)
38
+
39
+ { message: 'Cart Cleared Successfully', cart: @cart, status: :updated }
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,75 @@
1
+ module Shop
2
+ class CartItem
3
+ attr_reader :cart_id, :product_id, :variant_id, :quantity, :size_id
4
+
5
+ def initialize(cart_id, product_id, variant_id, size_id = nil)
6
+ @cart = ::Cart.find_by(id: cart_id) if cart_id
7
+ @product = ::Product.find_by(id: product_id) if product_id
8
+ @variant = ::Variant.find_by(id: variant_id) if variant_id
9
+ @size = ::Size.find_by(id: size_id) if size_id
10
+ end
11
+
12
+ # Cart Items
13
+ def cart_items
14
+ cart_items = @cart.cart_items.order(created_at: :desc)
15
+ if cart_items.present?
16
+ { message: 'Cart Items Found Successfully', cart_items: cart_items, status: :found }
17
+ else
18
+ { message: 'No Cart Items Found', cart_items: nil, status: :not_found }
19
+ end
20
+ end
21
+
22
+ # Creates a new Cart Item
23
+ def create(quantity, amount)
24
+ return { message: 'Cart not found', cart_item: nil, status: :not_found } unless @cart
25
+
26
+ cart_item = ::CartItem.new(cart_id: @cart.id, product_id: @product.id, variant_id: @variant.id, size_id: @size.id, quantity: quantity, amount: amount)
27
+ if cart_item.save
28
+ update_cart_amount(amount, 'add')
29
+ { message: 'Item Added Successfully', cart_item: cart_item, status: :created }
30
+ else
31
+ { message: cart_item.errors.full_messages, cart_item: nil, status: :unprocessable_entity }
32
+ end
33
+ end
34
+
35
+ # Update Cart Item Quantity
36
+ def update_quantity(cart_item_id, quantity, amount, key)
37
+ return { message: 'Cart Item not found', cart_item: nil, status: :not_found } unless (cart_item = ::CartItem.find_by(id: cart_item_id))
38
+
39
+ quantity = key == 'add' ? +quantity : -quantity
40
+ new_amount = key == 'add' ? +amount : -amount
41
+ old_quantity = cart_item.quantity
42
+ old_amount = cart_item.amount
43
+ if cart_item.update(quantity: old_quantity + quantity, amount: old_amount + new_amount)
44
+ update_cart_amount(amount, key)
45
+ { message: "Item #{key.capitalize}ed Successfully", cart_item: cart_item, status: :updated }
46
+ else
47
+ { message: cart_item.errors.full_messages, cart_item: nil, status: :unprocessable_entity }
48
+ end
49
+ end
50
+
51
+ # Deletes the Cart Item
52
+ def delete(cart_item_id)
53
+ return { message: 'Cart Item not found', cart_item: nil, status: :not_found } unless (cart_item = ::CartItem.find_by(id: cart_item_id))
54
+
55
+ if cart_item.destroy
56
+ update_cart_amount(cart_item.amount, 'remove')
57
+ { message: 'Cart Item Deleted Successfully', cart_item: nil, status: :deleted }
58
+ else
59
+ { message: cart_item.errors.full_messages, cart_item: nil, status: :unprocessable_entity }
60
+ end
61
+ end
62
+
63
+ private
64
+
65
+ def update_cart_amount(amount, key)
66
+ previous_amount = @cart.total_amount
67
+ new_amount = if key == 'add'
68
+ +amount
69
+ else
70
+ -amount
71
+ end
72
+ @cart.update(total_amount: previous_amount + new_amount)
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,52 @@
1
+ module Shop
2
+ class Product
3
+ attr_reader :user_id, :name, :price, :description, :delivery_fee, :country
4
+
5
+ def initialize(user_id)
6
+ @user_id = user_id
7
+ end
8
+
9
+ # Specific User Products
10
+ def specific_user_products(order, q)
11
+ products = ::Product.where(user_id: @user_id).order(created_at: order)
12
+ products = products.where('LOWER(name) ILIKE :query OR LOWER(country) ILIKE :query', query: "%#{q.downcase}%") if q.present?
13
+ if products.present?
14
+ { message: 'Product Found Successfully', products: products, status: :found }
15
+ else
16
+ { message: 'No Product Found For This User', products: [], status: :not_found }
17
+ end
18
+ end
19
+
20
+ # Creates a new product
21
+ def create(name, price, description, delivery_fee, country)
22
+ product = ::Product.new(user_id: @user_id, name: , price: ,description: , delivery_fee: , country: )
23
+ if product.save
24
+ { message: 'Product Created Successfully', product: product, status: :created }
25
+ else
26
+ { message: product.errors.full_messages, product: nil, status: :unprocessable_entity }
27
+ end
28
+ end
29
+
30
+ # Updates an existing product
31
+ def update(product_hash, product_id)
32
+ return { message: 'Product not found', product: nil, status: :not_found } unless (product = ::Product.find_by(id: product_id))
33
+
34
+ if product.update(product_hash)
35
+ { message: 'Product Updated Successfully', product: product, status: :updated }
36
+ else
37
+ { message: product.errors.full_messages, product: nil, status: :unprocessable_entity }
38
+ end
39
+ end
40
+
41
+ # Deletes the product
42
+ def delete(product_id)
43
+ return { message: 'Product not found', product: nil, status: :not_found } unless (product = ::Product.find_by(id: product_id))
44
+
45
+ if product.destroy
46
+ { message: 'Product Deleted Successfully', product: nil, status: :deleted }
47
+ else
48
+ { message: product.errors.full_messages, product: nil, status: :unprocessable_entity }
49
+ end
50
+ end
51
+ end
52
+ end
data/lib/shop/size.rb ADDED
@@ -0,0 +1,61 @@
1
+ module Shop
2
+ class Size
3
+ attr_reader :variant_id, :name, :short_form, :quantity
4
+
5
+ def initialize
6
+ super
7
+ end
8
+
9
+ # Specific Variant Sizes
10
+ def specific_variant_sizes(variant_id, order, q)
11
+ sizes = ::Size.where(variant_id: variant_id).order(created_at: order)
12
+ sizes = sizes.where('LOWER(name) ILIKE :query OR LOWER(short_name) ILIKE :query', query: "%#{q.downcase}%") if q.present?
13
+ if sizes.present?
14
+ { message: 'Sizes Found Successfully', sizes: sizes, status: :found }
15
+ else
16
+ { message: 'No Sizes Found For This Variant', sizes: nil, status: :not_found }
17
+ end
18
+ end
19
+
20
+ # Creates a Single Size
21
+ def create_single_size(variant_id, name, short_form, in_stock)
22
+ size = ::Size.new(variant_id: variant_id, name: name, short_form: short_form, in_stock: in_stock)
23
+ if size.save
24
+ { message: 'Size Created Successfully', size: size, status: :created }
25
+ else
26
+ { message: size.errors.full_messages, size: nil, status: :unprocessable_entity }
27
+ end
28
+ end
29
+
30
+ # Create Multiple Sizes
31
+ def create_multiple_sizes(multiple_sizes_array)
32
+ if ::Size.insert_all(multiple_sizes_array)
33
+ { message: 'Sizes Created Successfully', size: nil, status: :created }
34
+ else
35
+ { message: "Not Created", size: nil, status: :unprocessable_entity }
36
+ end
37
+ end
38
+
39
+ # Updates an existing Size
40
+ def update(size_id, size_hash)
41
+ return { message: 'Size not found', size: nil, status: :not_found } unless (@size = ::Size.find_by(id: size_id))
42
+
43
+ if @size.update(size_hash)
44
+ { message: 'Size Updated Successfully', size: @size, status: :updated }
45
+ else
46
+ { message: @size.errors.full_messages, size: nil, status: :unprocessable_entity }
47
+ end
48
+ end
49
+
50
+ # Deletes the Size
51
+ def delete(size_id)
52
+ return { message: 'Size not found', size: nil, status: :not_found } unless (@size = ::Size.find_by(id: size_id))
53
+
54
+ if @size.destroy
55
+ { message: 'Size Deleted Successfully', size: nil, status: :deleted }
56
+ else
57
+ { message: @variant.errors.full_messages, size: nil, status: :unprocessable_entity }
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,51 @@
1
+ module Shop
2
+ class Variant
3
+ attr_reader :product_id, :variant_id, :name, :color
4
+
5
+ def initialize
6
+ super
7
+ end
8
+
9
+ def specific_product_variants(product_id, order, q)
10
+ variants = ::Variant.where(product_id: product_id).order(created_at: order)
11
+ variants = variants.where('LOWER(name) ILIKE :query OR LOWER(color) ILIKE :query ', query: "%#{q.downcase}%") if q.present?
12
+ if variants.present?
13
+ { message: 'Variants Found Successfully', variants: variants, status: :found }
14
+ else
15
+ { message: 'No Variants Found For This Product', variants: nil, status: :not_found }
16
+ end
17
+ end
18
+
19
+ # Creates a new Variant
20
+ def create(product_id, name, color)
21
+ variant = ::Variant.new(product_id: product_id, name: name, color: color)
22
+ if variant.save
23
+ { message: 'Variant Created Successfully', variant: variant, status: :created }
24
+ else
25
+ { message: variant.errors.full_messages, variant: nil, status: :unprocessable_entity }
26
+ end
27
+ end
28
+
29
+ # Updates an existing Variant
30
+ def update(variant_id, variant_hash)
31
+ return { message: 'Variant not found', variant: nil, status: :not_found } unless (variant = ::Variant.find_by(id: variant_id))
32
+
33
+ if variant.update(variant_hash)
34
+ { message: 'Variant Updated Successfully', variant: variant, status: :updated }
35
+ else
36
+ { message: variant.errors.full_messages, variant: nil, status: :unprocessable_entity }
37
+ end
38
+ end
39
+
40
+ # Deletes the Variant
41
+ def delete(variant_id)
42
+ return { message: 'Variant not found', variant: nil, status: :not_found } unless (variant = ::Variant.find_by(id: variant_id))
43
+
44
+ if variant.destroy
45
+ { message: 'Variant Deleted Successfully', variant: nil, status: :deleted }
46
+ else
47
+ { message: variant.errors.full_messages, variant: nil, status: :unprocessable_entity }
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Shop
4
+ VERSION = "0.1.0"
5
+ end
data/sig/shop/cart.rbs ADDED
@@ -0,0 +1,14 @@
1
+ module Shop
2
+ class Cart
3
+ attr_reader user_id: untyped
4
+
5
+ @cart: untyped
6
+ @user_id: untyped
7
+
8
+ def initialize: (Integer) -> { message: String, cart: Cart | nil, status: Symbol }
9
+ def clear: () -> { message: String, cart: Cart | nil, status: Symbol }
10
+ def create: () -> { message: String, cart: Cart | nil, status: Symbol }
11
+ def delete: () -> { message: String, cart: Cart | nil, status: Symbol }
12
+ def specific_user_cart: () -> { message: String, cart: Cart | nil, status: Symbol }
13
+ end
14
+ end
@@ -0,0 +1,24 @@
1
+ module Shop
2
+ class CartItem
3
+ attr_reader cart_id: untyped
4
+ attr_reader product_id: untyped
5
+ attr_reader variant_id: untyped
6
+ attr_reader quantity: untyped
7
+ attr_reader size_id: untyped
8
+
9
+ @cart: untyped
10
+ @product: untyped
11
+ @variant: untyped
12
+ @size: untyped
13
+
14
+ def initialize: (Integer, Integer, Integer, nil | Integer) -> untyped
15
+ def cart_items: () -> { message: String, cart_item: Array[CartItem] | nil, status: Symbol }
16
+ def create: (Integer, Float) -> { message: String, cart_item: CartItem | nil, status: Symbol }
17
+ def delete: (Integer) -> { message: String, cart_item: CartItem | nil, status: Symbol }
18
+ def update_quantity: (Integer, Integer, Float, 'add' | 'remove') -> { message: String, cart_item: CartItem | nil, status: Symbol }
19
+
20
+ private
21
+
22
+ def update_cart_amount: -> untyped
23
+ end
24
+ end
@@ -0,0 +1,7 @@
1
+ module Shop
2
+ module Generators
3
+ class InstallGenerator
4
+ @prev_migration_nr: untyped
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,19 @@
1
+ module Shop
2
+ class Product
3
+ attr_reader country: untyped
4
+ attr_reader delivery_fee: untyped
5
+ attr_reader description: untyped
6
+ attr_reader name: untyped
7
+ attr_reader price: untyped
8
+ attr_reader user_id: untyped
9
+
10
+ @product: untyped
11
+ @product_hash: Hash[untyped, untyped]
12
+
13
+ def initialize: (Integer) -> untyped
14
+ def create: (String, Float, String | nil, Float | nil, String | nil) -> { message: String, product: Product | nil, status: Symbol }
15
+ def specific_user_products: ((:asc | :desc), String | nil) -> { message: String, products: Array[Product] | nil, status: Symbol }
16
+ def update: (Hash[Symbol, Integer | String | Float], Integer) -> { message: String, product: Product | nil, status: Symbol }
17
+ def delete: (Integer) -> { message: String, product: Product | nil, status: Symbol }
18
+ end
19
+ end
data/sig/shop/size.rbs ADDED
@@ -0,0 +1,18 @@
1
+ module Shop
2
+ class Size
3
+ attr_reader name: untyped
4
+ attr_reader product_id: untyped
5
+ attr_reader quantity: untyped
6
+ attr_reader short_form: untyped
7
+ attr_reader variant_id: untyped
8
+
9
+ @variant: untyped
10
+ @size: untyped
11
+
12
+ def specific_variant_sizes: (Integer, (:asc | :desc), String | nil) -> { message: String, sizes: Array[Size] | nil, status: Symbol }
13
+ def create_single_size: (Integer | nil, String, String, Integer) -> { message: String, size: Size | nil, status: Symbol }
14
+ def create_multiple_sizes: (Array[Hash[Symbol, String | Float | Integer]]) -> { message: String, size: Size | nil, status: Symbol }
15
+ def delete: (Integer) -> { message: String, size: Size | nil, status: Symbol }
16
+ def update: (Integer, Hash[Symbol, Integer | Float | String]) -> { message: String, size: Size | nil, status: Symbol }
17
+ end
18
+ end
@@ -0,0 +1,16 @@
1
+ module Shop
2
+ class Variant
3
+ attr_reader color: untyped
4
+ attr_reader name: untyped
5
+ attr_reader product_id: untyped
6
+ attr_reader variant_id: untyped
7
+
8
+ @product: untyped
9
+ @variant: untyped
10
+
11
+ def create: (Integer, String, String) -> { message: String, variant: Variant | nil, status: Symbol }
12
+ def specific_product_variants: (Integer, (:asc | :desc), String | nil) -> { message: String, variants: Array[Variant] | nil, status: Symbol }
13
+ def update: (Integer, Hash[Symbol, String | Float | Integer]) -> { message: String, variant: Variant | nil, status: Symbol }
14
+ def delete: (Integer) -> { message: String, variant: Variant | nil, status: Symbol }
15
+ end
16
+ end
data/sig/shop.rbs ADDED
@@ -0,0 +1,4 @@
1
+ module CartManagement
2
+ VERSION: String
3
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
+ end
@@ -0,0 +1,26 @@
1
+ # spec/generators/install_generator_spec.rb
2
+ require 'rails_helper'
3
+ require "shop/generators/install_generator"
4
+
5
+ RSpec.describe Shop::Generators::InstallGenerator, type: :generator do
6
+ destination File.expand_path('../../tmp/generators', __FILE__)
7
+
8
+ # Include the generator test case behavior
9
+ include Rails::Generators::TestCase::Behavior
10
+
11
+ before(:all) do
12
+ prepare_destination
13
+ run_generator
14
+ end
15
+
16
+ it "generates a migration file" do
17
+ expect(destination_root).to have_structure {
18
+ directory("db") do
19
+ directory("migrate") do
20
+ migration_file = file(/.*create_carts.rb/)
21
+ expect(migration_file).to exist
22
+ end
23
+ end
24
+ }
25
+ end
26
+ end
@@ -0,0 +1,23 @@
1
+ # spec/rails_helper.rb
2
+
3
+ # Require RSpec and any other necessary testing libraries
4
+ # require "rspec/rails"
5
+ require "shop"
6
+
7
+ # Requires supporting ruby files with custom matchers and macros, etc,
8
+ # in spec/support/ and its subdirectories.
9
+
10
+ RSpec.configure do |config|
11
+ # If you want to run your tests within a transaction, uncomment this line
12
+ # This will make tests faster by rolling back changes after each test
13
+ # config.use_transactional_fixtures = true
14
+
15
+ # Add additional requires or configurations here
16
+ # e.g., if you are using FactoryBot for factories
17
+ config.include FactoryBot::Syntax::Methods
18
+
19
+ # Configure how your tests are run
20
+ config.fixture_path = "#{::Rails.root}/spec/fixtures" # Path for fixture files
21
+ config.infer_spec_type_from_file_location! # Automatically set test types based on file location
22
+ config.filter_rails_from_backtrace! # Filter out Rails gems from backtrace
23
+ end
@@ -0,0 +1,33 @@
1
+ # spec/spec_helper.rb
2
+
3
+ # This file is generated by the `rspec --init` command.
4
+ # It is a good idea to add `require 'rspec/expectations'` here.
5
+
6
+ RSpec.configure do |config|
7
+ # Enables the `:focus` filter, allowing you to run only focused tests.
8
+ config.filter_run_when_matching :focus
9
+
10
+ # Run all examples in random order to surface order dependencies.
11
+ config.order = :random
12
+
13
+ # Print the seed used for random ordering.
14
+ Kernel.srand config.seed
15
+
16
+ # Enable the expectation syntax for more readable tests.
17
+ config.expect_with :rspec do |c|
18
+ c.syntax = :expect
19
+ end
20
+
21
+ # Enable the mock framework.
22
+ config.mock_with :rspec do |mocks|
23
+ mocks.verify_partial_doubles = true
24
+ end
25
+
26
+ # Disable RSpec's monkey patching of Kernel and Object.
27
+ config.disable_monkey_patching!
28
+
29
+ # Enable the use of `let` and `subject` outside of `describe` blocks.
30
+ config.include RSpec::Mocks::ExampleMethods
31
+
32
+ # Additional configurations can go here.
33
+ end
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: e-commerce_shop
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Fahadbutt
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2024-10-24 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: This gem provides a comprehensive solution for managing shopping carts,
14
+ products, and variants in e-commerce applications. It supports flexible product
15
+ creation, updates, and variant handling, along with efficient cart management functionality.
16
+ email:
17
+ - buttf5169@gmail.com
18
+ executables: []
19
+ extensions: []
20
+ extra_rdoc_files: []
21
+ files:
22
+ - lib/generators/install_generator.rb
23
+ - lib/shop/cart.rb
24
+ - lib/shop/cart_item.rb
25
+ - lib/shop/product.rb
26
+ - lib/shop/size.rb
27
+ - lib/shop/variant.rb
28
+ - lib/shop/version.rb
29
+ - sig/shop.rbs
30
+ - sig/shop/cart.rbs
31
+ - sig/shop/cart_item.rbs
32
+ - sig/shop/generators/install_generator.rbs
33
+ - sig/shop/product.rbs
34
+ - sig/shop/size.rbs
35
+ - sig/shop/variant.rbs
36
+ - spec/generators/install_generator_spec.rb
37
+ - spec/rails_helper.rb
38
+ - spec/spec_helper.rb
39
+ homepage:
40
+ licenses:
41
+ - MIT
42
+ metadata: {}
43
+ post_install_message: |2
44
+ Thank you for installing Shop Gem!
45
+
46
+ To complete the installation, please run:
47
+
48
+ rails g shop:install
49
+ rdoc_options: []
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: 2.6.0
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ requirements: []
63
+ rubygems_version: 3.3.7
64
+ signing_key:
65
+ specification_version: 4
66
+ summary: A gem to manage shopping carts, products, and variants with flexible and
67
+ customizable features for e-commerce platforms.
68
+ test_files: []