solidus_advanced_pricing 0.1.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.
Files changed (70) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +53 -0
  3. data/.gem_release.yml +5 -0
  4. data/.github/stale.yml +1 -0
  5. data/.github/workflows/lint.yml +25 -0
  6. data/.github/workflows/test.yml +86 -0
  7. data/.github_changelog_generator +2 -0
  8. data/.gitignore +21 -0
  9. data/.rspec +2 -0
  10. data/.rubocop.yml +5 -0
  11. data/CHANGELOG.md +3 -0
  12. data/Gemfile +64 -0
  13. data/LICENSE +26 -0
  14. data/README.md +377 -0
  15. data/Rakefile +41 -0
  16. data/app/assets/javascripts/spree/backend/solidus_advanced_pricing.js +2 -0
  17. data/app/assets/javascripts/spree/frontend/solidus_advanced_pricing.js +2 -0
  18. data/app/assets/stylesheets/spree/backend/solidus_advanced_pricing.css +4 -0
  19. data/app/assets/stylesheets/spree/frontend/solidus_advanced_pricing.css +4 -0
  20. data/app/decorators/models/solidus_advanced_pricing/spree/app_configuration_decorator.rb +17 -0
  21. data/app/decorators/models/solidus_advanced_pricing/spree/permitted_attributes_decorator.rb +27 -0
  22. data/app/decorators/models/solidus_advanced_pricing/spree/price_decorator.rb +56 -0
  23. data/app/decorators/models/solidus_advanced_pricing/spree/role_decorator.rb +24 -0
  24. data/app/decorators/models/solidus_advanced_pricing/spree/variant_decorator.rb +52 -0
  25. data/app/models/solidus_advanced_pricing/price_selector.rb +73 -0
  26. data/app/models/solidus_advanced_pricing/price_type.rb +80 -0
  27. data/app/models/solidus_advanced_pricing/price_type_cache.rb +45 -0
  28. data/app/models/solidus_advanced_pricing/pricing_options.rb +107 -0
  29. data/app/overrides/spree/admin/prices/_form/add_advanced_fields.html.erb.deface +2 -0
  30. data/app/overrides/spree/admin/prices/_master_variant_table/add_advanced_columns.html.erb.deface +2 -0
  31. data/app/overrides/spree/admin/prices/_master_variant_table/add_advanced_headers.html.erb.deface +4 -0
  32. data/app/overrides/spree/admin/prices/_table/add_advanced_columns.html.erb.deface +2 -0
  33. data/app/overrides/spree/admin/prices/_table/add_advanced_headers.html.erb.deface +4 -0
  34. data/app/overrides/spree/admin/shared/_configuration_menu/add_price_types_link.html.erb.deface +4 -0
  35. data/bin/console +17 -0
  36. data/bin/rails +7 -0
  37. data/bin/rails-engine +13 -0
  38. data/bin/rails-sandbox +16 -0
  39. data/bin/rake +7 -0
  40. data/bin/sandbox +85 -0
  41. data/bin/setup +8 -0
  42. data/config/locales/en.yml +44 -0
  43. data/config/routes.rb +34 -0
  44. data/db/migrate/20260915000001_create_solidus_advanced_pricing_price_types.rb +16 -0
  45. data/db/migrate/20260915000002_seed_solidus_advanced_pricing_price_types.rb +34 -0
  46. data/db/migrate/20260915000003_add_advanced_pricing_to_spree_prices.rb +21 -0
  47. data/docs/superpowers/specs/2026-09-14-solidus-advanced-pricing-design.md +351 -0
  48. data/lib/components/admin/solidus_admin/price_types/index/component.rb +65 -0
  49. data/lib/controllers/admin/solidus_admin/price_types_controller.rb +26 -0
  50. data/lib/controllers/api/spree/api/prices_controller.rb +32 -0
  51. data/lib/controllers/backend/spree/admin/price_types_controller.rb +40 -0
  52. data/lib/generators/solidus_advanced_pricing/install/install_generator.rb +33 -0
  53. data/lib/generators/solidus_advanced_pricing/install/templates/initializer.rb +7 -0
  54. data/lib/solidus_advanced_pricing/configuration.rb +21 -0
  55. data/lib/solidus_advanced_pricing/engine.rb +41 -0
  56. data/lib/solidus_advanced_pricing/testing_support/factories/price_type_factory.rb +13 -0
  57. data/lib/solidus_advanced_pricing/testing_support/factories.rb +4 -0
  58. data/lib/solidus_advanced_pricing/version.rb +5 -0
  59. data/lib/solidus_advanced_pricing.rb +19 -0
  60. data/lib/views/api/spree/api/prices/_price.json.jbuilder +8 -0
  61. data/lib/views/api/spree/api/prices/index.json.jbuilder +3 -0
  62. data/lib/views/api/spree/api/prices/show.json.jbuilder +1 -0
  63. data/lib/views/backend/spree/admin/price_types/_form.html.erb +20 -0
  64. data/lib/views/backend/spree/admin/price_types/edit.html.erb +9 -0
  65. data/lib/views/backend/spree/admin/price_types/index.html.erb +31 -0
  66. data/lib/views/backend/spree/admin/price_types/new.html.erb +9 -0
  67. data/lib/views/backend/spree/admin/prices/_advanced_columns.html.erb +7 -0
  68. data/lib/views/backend/spree/admin/prices/_advanced_fields.html.erb +46 -0
  69. data/solidus_advanced_pricing.gemspec +39 -0
  70. metadata +228 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 3dd5e3bb515d712553025000029ebf739470339c09c0a615b70084a134ceff3c
4
+ data.tar.gz: 065ce411b91483ac3e6b3ef13f09144d5015c986cc27fbbff9c1544bf4978355
5
+ SHA512:
6
+ metadata.gz: 740e98329afaa1a757bde107a9ea231d22b4a3c92ae0840b0a3ea9462b0d6227b3d93acfc05a4c27a43ec285b4e0fc02b99056f3352950e6047ac7919a975c56
7
+ data.tar.gz: e4426d9b9fac0bda2db9a87f228f424ced485a16003c5ec220dfa845756cdf87c637605f2c8e6fe0f4802149b9f16f6207efab762b43db73e0510f2ab25bea13
@@ -0,0 +1,53 @@
1
+ version: 2.1
2
+
3
+ orbs:
4
+ # Required for feature specs.
5
+ browser-tools: circleci/browser-tools@1.1
6
+
7
+ # Always take the latest version of the orb, this allows us to
8
+ # run specs against Solidus supported versions only without the need
9
+ # to change this configuration every time a Solidus version is released
10
+ # or goes EOL.
11
+ solidusio_extensions: solidusio/extensions@volatile
12
+
13
+ jobs:
14
+ run-specs-with-sqlite:
15
+ executor: solidusio_extensions/sqlite
16
+ steps:
17
+ - browser-tools/install-chrome
18
+ - solidusio_extensions/run-tests
19
+ run-specs-with-postgres:
20
+ executor: solidusio_extensions/postgres
21
+ steps:
22
+ - browser-tools/install-chrome
23
+ - solidusio_extensions/run-tests
24
+ run-specs-with-mysql:
25
+ executor: solidusio_extensions/mysql
26
+ steps:
27
+ - browser-tools/install-chrome
28
+ - solidusio_extensions/run-tests
29
+ lint-code:
30
+ executor: solidusio_extensions/sqlite-memory
31
+ steps:
32
+ - solidusio_extensions/lint-code
33
+
34
+ workflows:
35
+ "Run specs on supported Solidus versions":
36
+ jobs:
37
+ - run-specs-with-sqlite
38
+ - run-specs-with-postgres
39
+ - run-specs-with-mysql
40
+ - lint-code
41
+
42
+ "Weekly run specs against main":
43
+ triggers:
44
+ - schedule:
45
+ cron: "0 0 * * 4" # every Thursday
46
+ filters:
47
+ branches:
48
+ only:
49
+ - main
50
+ jobs:
51
+ - run-specs-with-sqlite
52
+ - run-specs-with-postgres
53
+ - run-specs-with-mysql
data/.gem_release.yml ADDED
@@ -0,0 +1,5 @@
1
+ bump:
2
+ recurse: false
3
+ file: 'lib/solidus_advanced_pricing/version.rb'
4
+ message: Bump SolidusAdvancedPricing to %{version}
5
+ tag: true
data/.github/stale.yml ADDED
@@ -0,0 +1 @@
1
+ _extends: .github
@@ -0,0 +1,25 @@
1
+ name: Lint
2
+
3
+ on: [pull_request]
4
+
5
+ concurrency:
6
+ group: lint-${{ github.ref_name }}
7
+ cancel-in-progress: ${{ github.ref_name != 'main' }}
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ jobs:
13
+ ruby:
14
+ name: Check Ruby
15
+ runs-on: ubuntu-24.04
16
+ steps:
17
+ - name: Checkout code
18
+ uses: actions/checkout@v3
19
+ - name: Install Ruby and gems
20
+ uses: ruby/setup-ruby@v1
21
+ with:
22
+ ruby-version: "3.2"
23
+ bundler-cache: true
24
+ - name: Lint Ruby files
25
+ run: bundle exec rubocop -ESP
@@ -0,0 +1,86 @@
1
+ name: Test
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ pull_request:
8
+ schedule:
9
+ - cron: "0 0 * * 4" # every Thursday
10
+
11
+ concurrency:
12
+ group: test-${{ github.ref_name }}
13
+ cancel-in-progress: ${{ github.ref_name != 'main' }}
14
+
15
+ permissions:
16
+ contents: read
17
+
18
+ jobs:
19
+ rspec:
20
+ name: Solidus ${{ matrix.solidus-branch }}, Rails ${{ matrix.rails-version }} and Ruby ${{ matrix.ruby-version }} on ${{ matrix.database }}
21
+ runs-on: ubuntu-24.04
22
+ strategy:
23
+ # false so one bad cell reports the whole matrix instead of cancelling the other
24
+ # 44 jobs -- version-specific breakage was surfacing one cell per round trip.
25
+ fail-fast: false
26
+ matrix:
27
+ rails-version:
28
+ - "7.0"
29
+ - "7.1"
30
+ - "7.2"
31
+ ruby-version:
32
+ - "3.1"
33
+ - "3.4"
34
+ solidus-branch:
35
+ - "v4.5"
36
+ database:
37
+ - "postgresql"
38
+ - "mysql"
39
+ - "sqlite"
40
+ exclude:
41
+ - ruby-version: "3.4"
42
+ rails-version: "7.0"
43
+ env:
44
+ CODECOV_COVERAGE_PATH: ./coverage/coverage.xml
45
+ # ubuntu-24.04 ships no running database, and solidusio/test-solidus-extension
46
+ # installs only client headers -- the caller must supply the servers.
47
+ # Credentials match the action's DB_HOST/DB_USERNAME (127.0.0.1, root/postgres,
48
+ # no password). Both start on every leg; sqlite ones simply ignore them.
49
+ services:
50
+ mysql:
51
+ image: mysql:8
52
+ env:
53
+ MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
54
+ ports:
55
+ - 3306:3306
56
+ options: >-
57
+ --health-cmd="mysqladmin ping --silent"
58
+ --health-interval=10s
59
+ --health-timeout=5s
60
+ --health-retries=10
61
+ postgres:
62
+ image: postgres:16
63
+ env:
64
+ POSTGRES_HOST_AUTH_METHOD: trust
65
+ ports:
66
+ - 5432:5432
67
+ options: >-
68
+ --health-cmd=pg_isready
69
+ --health-interval=10s
70
+ --health-timeout=5s
71
+ --health-retries=10
72
+ steps:
73
+ - uses: actions/checkout@v4
74
+ - name: Run extension tests
75
+ uses: solidusio/test-solidus-extension@main
76
+ with:
77
+ database: ${{ matrix.database }}
78
+ rails-version: ${{ matrix.rails-version }}
79
+ ruby-version: ${{ matrix.ruby-version }}
80
+ solidus-branch: ${{ matrix.solidus-branch }}
81
+ - name: Upload coverage reports to Codecov
82
+ uses: codecov/codecov-action@v5
83
+ continue-on-error: true
84
+ with:
85
+ token: ${{ secrets.CODECOV_TOKEN }}
86
+ files: ${{ env.CODECOV_COVERAGE_PATH }}
@@ -0,0 +1,2 @@
1
+ issues=false
2
+ exclude-labels=infrastructure
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ *.gem
2
+ \#*
3
+ *~
4
+ .#*
5
+ .DS_Store
6
+ .idea
7
+ .project
8
+ .sass-cache
9
+ coverage
10
+ Gemfile.lock
11
+ Gemfile-local
12
+ tmp
13
+ nbproject
14
+ pkg
15
+ *.swp
16
+ spec/dummy
17
+ spec/examples.txt
18
+ /sandbox
19
+ .rvmrc
20
+ .ruby-version
21
+ .ruby-gemset
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,5 @@
1
+ require:
2
+ - solidus_dev_support/rubocop
3
+
4
+ AllCops:
5
+ NewCops: disable
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ # Changelog
2
+
3
+ See https://github.com/solidusio-contrib/solidus_advanced_pricing/releases or OLD_CHANGELOG.md for older versions.
data/Gemfile ADDED
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
5
+
6
+ branch = ENV.fetch("SOLIDUS_BRANCH", "main")
7
+ gem "solidus", github: "solidusio/solidus", branch: branch
8
+ gem "solidus_backend", github: "solidusio/solidus", branch: branch, glob: "backend/*.gemspec"
9
+ gem "solidus_api", github: "solidusio/solidus", branch: branch, glob: "api/*.gemspec"
10
+ # This gem's solidus_admin support needs SolidusAdmin::ResourcesController, added
11
+ # in Solidus 4.5 (solidus_admin itself ships from 4.3). Lexical compare matches the
12
+ # solidus_frontend idiom below and breaks at v4.10, which Solidus has not reached.
13
+ if branch == "main" || branch >= "v4.5"
14
+ gem "solidus_admin", github: "solidusio/solidus", branch: branch, glob: "admin/*.gemspec"
15
+ end
16
+
17
+ # The solidus_frontend gem has been pulled out since v3.2
18
+ if branch >= "v3.2"
19
+ gem "solidus_frontend"
20
+ elsif branch == "main"
21
+ gem "solidus_frontend", github: "solidusio/solidus_frontend"
22
+ else
23
+ gem "solidus_frontend", github: "solidusio/solidus", branch: branch
24
+ end
25
+
26
+ # solidus_dev_support pins simplecov-cobertura "~> 2.1", whose REXML-based
27
+ # formatter raises "Malformed XML: No root element" on rexml 3.4.x. Only bites
28
+ # when CODECOV_COVERAGE_PATH is set, i.e. in CI.
29
+ gem "rexml", "< 3.4"
30
+
31
+ rails_version = ENV.fetch("RAILS_VERSION", "7.0")
32
+ gem "rails", "~> #{rails_version}"
33
+
34
+ case ENV.fetch("DB", nil)
35
+ when "mysql"
36
+ gem "mysql2"
37
+ when "postgresql"
38
+ gem "pg"
39
+ else
40
+ gem "sqlite3", (rails_version < "7.2") ? "~> 1.4" : "~> 2.0"
41
+ end
42
+
43
+ if rails_version == "7.0"
44
+ gem "concurrent-ruby", "< 1.3.5"
45
+ end
46
+
47
+ if RUBY_VERSION >= "3.4"
48
+ # Solidus Promotions uses CSV but does not have it as dependency yet.
49
+ gem "csv"
50
+ end
51
+
52
+ # While we still support Ruby < 3 we need to workaround a limitation in
53
+ # the 'async' gem that relies on the latest ruby, since RubyGems doesn't
54
+ # resolve gems based on the required ruby version.
55
+ gem "async", "< 3" if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("3")
56
+
57
+ gemspec
58
+
59
+ # Use a local Gemfile to include development dependencies that might not be
60
+ # relevant for the project or for other contributors, e.g. pry-byebug.
61
+ #
62
+ # We use `send` instead of calling `eval_gemfile` to work around an issue with
63
+ # how Dependabot parses projects: https://github.com/dependabot/dependabot-core/issues/1658.
64
+ send(:eval_gemfile, "Gemfile-local") if File.exist? "Gemfile-local"
data/LICENSE ADDED
@@ -0,0 +1,26 @@
1
+ Copyright (c) 2026 Patrick McMorran
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification,
5
+ are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice,
8
+ this list of conditions and the following disclaimer.
9
+ * Redistributions in binary form must reproduce the above copyright notice,
10
+ this list of conditions and the following disclaimer in the documentation
11
+ and/or other materials provided with the distribution.
12
+ * Neither the name Solidus nor the names of its contributors may be used to
13
+ endorse or promote products derived from this software without specific
14
+ prior written permission.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.