@spree/docs 0.1.229 → 0.1.231
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.
- package/dist/api-reference/store.yaml +78 -78
- package/dist/developer/agentic/agent-skills.md +1 -1
- package/dist/developer/cli/quickstart.md +2 -2
- package/dist/developer/core-concepts/addresses.md +13 -0
- package/dist/developer/core-concepts/calculators.md +6 -1
- package/dist/developer/core-concepts/carts.md +19 -1
- package/dist/developer/core-concepts/catalogs.md +51 -2
- package/dist/developer/core-concepts/channels.md +20 -1
- package/dist/developer/core-concepts/commissions.md +70 -1
- package/dist/developer/core-concepts/companies.md +74 -0
- package/dist/developer/core-concepts/customers.md +17 -5
- package/dist/developer/core-concepts/data-privacy.md +20 -7
- package/dist/developer/core-concepts/delivery-setup.md +57 -0
- package/dist/developer/core-concepts/discounts.md +7 -0
- package/dist/developer/core-concepts/events.md +13 -7
- package/dist/developer/core-concepts/fees.md +20 -0
- package/dist/developer/core-concepts/fulfillments.md +3 -3
- package/dist/developer/core-concepts/imports-exports.md +21 -5
- package/dist/developer/core-concepts/inventory.md +73 -1
- package/dist/developer/core-concepts/markets.md +5 -6
- package/dist/developer/core-concepts/media.md +66 -1
- package/dist/developer/core-concepts/metafields.md +1 -1
- package/dist/developer/core-concepts/order-totals.md +18 -1
- package/dist/developer/core-concepts/orders.md +2 -1
- package/dist/developer/core-concepts/payments.md +100 -20
- package/dist/developer/core-concepts/pricing.md +13 -8
- package/dist/developer/core-concepts/products.md +52 -1
- package/dist/developer/core-concepts/reporting.md +5 -5
- package/dist/developer/core-concepts/returns-exchanges-claims.md +41 -2
- package/dist/developer/core-concepts/search-filtering.md +1 -2
- package/dist/developer/core-concepts/sellers.md +109 -2
- package/dist/developer/core-concepts/slugs.md +1 -1
- package/dist/developer/core-concepts/staff-roles.md +23 -3
- package/dist/developer/core-concepts/stores.md +21 -0
- package/dist/developer/core-concepts/taxes.md +43 -0
- package/dist/developer/core-concepts/translations.md +9 -0
- package/dist/developer/core-concepts/webhooks.md +45 -3
- package/dist/developer/create-spree-app/quickstart.md +10 -10
- package/dist/developer/dashboard/deployment.md +4 -4
- package/dist/developer/dashboard/recipes/attribute-end-to-end.md +1 -1
- package/dist/developer/deployment/docker.md +2 -2
- package/dist/developer/how-to/custom-promotion.md +33 -13
- package/dist/developer/multi-tenant/quickstart.md +6 -6
- package/dist/developer/storefront/nextjs/testing.md +2 -2
- package/package.json +1 -1
|
@@ -21,7 +21,7 @@ Rules determine whether a promotion is eligible for a given order. Each rule imp
|
|
|
21
21
|
|
|
22
22
|
Create a new class inheriting from `Spree::PromotionRule`:
|
|
23
23
|
|
|
24
|
-
```ruby app/models/spree/promotion/rules/minimum_quantity.rb
|
|
24
|
+
```ruby server/app/models/spree/promotion/rules/minimum_quantity.rb
|
|
25
25
|
module Spree
|
|
26
26
|
class Promotion
|
|
27
27
|
module Rules
|
|
@@ -67,7 +67,7 @@ The `options` hash passed to `eligible?` can include `:user`, `:email`, and othe
|
|
|
67
67
|
|
|
68
68
|
Rules use Spree's preference system for configuration. Each preference creates getter/setter methods automatically:
|
|
69
69
|
|
|
70
|
-
```ruby
|
|
70
|
+
```ruby server/app/models/spree/promotion/rules/minimum_quantity.rb
|
|
71
71
|
preference :amount, :decimal, default: 100.00
|
|
72
72
|
preference :operator, :string, default: 'gte'
|
|
73
73
|
preference :category_ids, :array, default: []
|
|
@@ -82,7 +82,7 @@ Available types: `:string`, `:integer`, `:decimal`, `:boolean`, `:array`.
|
|
|
82
82
|
|
|
83
83
|
### Step 2: Register the Rule
|
|
84
84
|
|
|
85
|
-
```ruby config/initializers/spree.rb
|
|
85
|
+
```ruby server/config/initializers/spree.rb
|
|
86
86
|
Rails.application.config.after_initialize do
|
|
87
87
|
Spree.promotions.rules << Spree::Promotion::Rules::MinimumQuantity
|
|
88
88
|
end
|
|
@@ -90,11 +90,31 @@ end
|
|
|
90
90
|
|
|
91
91
|
Registered rules are discoverable at `/api/v3/admin/promotion_rules/types` together with their preference schema, and the dashboard's promotion editor is built on that endpoint — your rule appears there with a generated preferences form, no UI work needed.
|
|
92
92
|
|
|
93
|
+
The API names your rule by its **shorthand** — the class name demodulized and underscored, so `Spree::Promotion::Rules::MinimumQuantity` is `minimum_quantity`. That is what `/types` returns, what a promotion payload sends, and what the locale key below is named after. The Ruby class name is never accepted on the wire:
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
```typescript Admin SDK
|
|
97
|
+
await adminClient.promotions.rules.create('promo_xxx', {
|
|
98
|
+
type: 'minimum_quantity',
|
|
99
|
+
preferences: { amount: 3 },
|
|
100
|
+
})
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
```bash cURL
|
|
104
|
+
curl -X POST 'https://api.mystore.com/api/v3/admin/promotions/promo_xxx/promotion_rules' \
|
|
105
|
+
-H 'X-Spree-API-Key: sk_xxx' \
|
|
106
|
+
-H 'Content-Type: application/json' \
|
|
107
|
+
-d '{ "type": "minimum_quantity", "preferences": { "amount": 3 } }'
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
Override `self.api_type` on the class when you need the wire value to stay put across a rename.
|
|
112
|
+
|
|
93
113
|
### Step 3: Add Translations
|
|
94
114
|
|
|
95
115
|
The rule's display name and description in the dashboard come from your locale file:
|
|
96
116
|
|
|
97
|
-
```yaml config/locales/en.yml
|
|
117
|
+
```yaml server/config/locales/en.yml
|
|
98
118
|
en:
|
|
99
119
|
spree:
|
|
100
120
|
promotion_rule_types:
|
|
@@ -107,7 +127,7 @@ en:
|
|
|
107
127
|
|
|
108
128
|
When your rule targets specific line items (not the whole order), implement `actionable?` so that item-level actions only discount matching items:
|
|
109
129
|
|
|
110
|
-
```ruby app/models/spree/promotion/rules/brand.rb
|
|
130
|
+
```ruby server/app/models/spree/promotion/rules/brand.rb
|
|
111
131
|
module Spree
|
|
112
132
|
class Promotion
|
|
113
133
|
module Rules
|
|
@@ -153,7 +173,7 @@ Three declarations make a discount action:
|
|
|
153
173
|
| `compute_amount(adjustable)` | The discount for one adjustable — a line item, fulfillment, or the order, matching your scope. Return a **negative** amount, or zero for "no discount". |
|
|
154
174
|
| `perform(options = {})` | Called when the promotion is activated. For discount actions, delegate to `apply_via_adjuster(options)`. |
|
|
155
175
|
|
|
156
|
-
```ruby app/models/spree/promotion/actions/tiered_discount.rb
|
|
176
|
+
```ruby server/app/models/spree/promotion/actions/tiered_discount.rb
|
|
157
177
|
module Spree
|
|
158
178
|
class Promotion
|
|
159
179
|
module Actions
|
|
@@ -195,7 +215,7 @@ With `discount_scope :order`, the winning amount is shared out proportionally ac
|
|
|
195
215
|
|
|
196
216
|
For actions that don't create discounts (awarding points, sending notifications), implement `perform` alone:
|
|
197
217
|
|
|
198
|
-
```ruby app/models/spree/promotion/actions/add_loyalty_points.rb
|
|
218
|
+
```ruby server/app/models/spree/promotion/actions/add_loyalty_points.rb
|
|
199
219
|
module Spree
|
|
200
220
|
class Promotion
|
|
201
221
|
module Actions
|
|
@@ -219,13 +239,13 @@ end
|
|
|
219
239
|
|
|
220
240
|
### Register and Translate
|
|
221
241
|
|
|
222
|
-
```ruby config/initializers/spree.rb
|
|
242
|
+
```ruby server/config/initializers/spree.rb
|
|
223
243
|
Rails.application.config.after_initialize do
|
|
224
244
|
Spree.promotions.actions << Spree::Promotion::Actions::TieredDiscount
|
|
225
245
|
end
|
|
226
246
|
```
|
|
227
247
|
|
|
228
|
-
```yaml config/locales/en.yml
|
|
248
|
+
```yaml server/config/locales/en.yml
|
|
229
249
|
en:
|
|
230
250
|
spree:
|
|
231
251
|
promotion_action_types:
|
|
@@ -240,7 +260,7 @@ Like rules, registered actions surface automatically in the dashboard's promotio
|
|
|
240
260
|
|
|
241
261
|
Not every charge or reduction is a promotion. A gift wrap fee, a payment surcharge, or loyalty pricing has no rules, no coupon codes, and no competition — it just needs to be on the order whenever it applies. That's an **adjuster**: a class invoked on every recalculation that owns a family of [Fee](../core-concepts/fees.md) or [Discount](../core-concepts/discounts.md) rows.
|
|
242
262
|
|
|
243
|
-
```ruby app/models/my_app/adjusters/gift_wrap.rb
|
|
263
|
+
```ruby server/app/models/my_app/adjusters/gift_wrap.rb
|
|
244
264
|
module MyApp
|
|
245
265
|
module Adjusters
|
|
246
266
|
class GiftWrap < Spree::Adjusters::Base
|
|
@@ -258,7 +278,7 @@ module MyApp
|
|
|
258
278
|
end
|
|
259
279
|
```
|
|
260
280
|
|
|
261
|
-
```ruby config/initializers/spree.rb
|
|
281
|
+
```ruby server/config/initializers/spree.rb
|
|
262
282
|
Rails.application.config.after_initialize do
|
|
263
283
|
Spree.adjusters << MyApp::Adjusters::GiftWrap
|
|
264
284
|
end
|
|
@@ -272,7 +292,7 @@ Custom discounts work the same way, writing `order.discounts` rows with your own
|
|
|
272
292
|
|
|
273
293
|
## Testing
|
|
274
294
|
|
|
275
|
-
```ruby spec/models/spree/promotion/rules/minimum_quantity_spec.rb
|
|
295
|
+
```ruby server/spec/models/spree/promotion/rules/minimum_quantity_spec.rb
|
|
276
296
|
require 'spec_helper'
|
|
277
297
|
|
|
278
298
|
RSpec.describe Spree::Promotion::Rules::MinimumQuantity do
|
|
@@ -300,7 +320,7 @@ RSpec.describe Spree::Promotion::Rules::MinimumQuantity do
|
|
|
300
320
|
end
|
|
301
321
|
```
|
|
302
322
|
|
|
303
|
-
```ruby spec/models/spree/promotion/actions/tiered_discount_spec.rb
|
|
323
|
+
```ruby server/spec/models/spree/promotion/actions/tiered_discount_spec.rb
|
|
304
324
|
require 'spec_helper'
|
|
305
325
|
|
|
306
326
|
RSpec.describe Spree::Promotion::Actions::TieredDiscount do
|
|
@@ -44,7 +44,7 @@ spree eject
|
|
|
44
44
|
|
|
45
45
|
### Adding gems
|
|
46
46
|
|
|
47
|
-
1. Add the following code to your `
|
|
47
|
+
1. Add the following code to your `server/Gemfile`:
|
|
48
48
|
|
|
49
49
|
```ruby
|
|
50
50
|
source "https://license:#{ENV['KEYGEN_LICENSE_KEY']}@rubygems.pkg.keygen.sh/#{ENV['KEYGEN_ACCOUNT_ID']}" do
|
|
@@ -66,10 +66,10 @@ spree eject
|
|
|
66
66
|
> In that case the Gemfile reads `KEYGEN_LICENSE_KEY` / `KEYGEN_ACCOUNT_ID` directly from
|
|
67
67
|
> your shell environment.
|
|
68
68
|
|
|
69
|
-
Wrap **every** `bundle install` in your `
|
|
69
|
+
Wrap **every** `bundle install` in your `server/Dockerfile` with the secret mounts. There
|
|
70
70
|
are usually two — one in the build stage and one in the dev stage:
|
|
71
71
|
|
|
72
|
-
```dockerfile
|
|
72
|
+
```dockerfile server/Dockerfile
|
|
73
73
|
COPY .ruby-version Gemfile Gemfile.lock ./
|
|
74
74
|
RUN bundle install # [!code --]
|
|
75
75
|
RUN --mount=type=secret,id=keygen_license_key,env=KEYGEN_LICENSE_KEY,required=false \ # [!code ++]
|
|
@@ -185,7 +185,7 @@ development by default, but `.lvh.me` (and your production domain) are not — r
|
|
|
185
185
|
`app.lvh.me` are rejected with a "Blocked hosts" error until you allow them. Add your root
|
|
186
186
|
domain to `config/environments/development.rb`:
|
|
187
187
|
|
|
188
|
-
```ruby
|
|
188
|
+
```ruby server/config/environments/development.rb
|
|
189
189
|
if (root_domain = ENV['SPREE_ROOT_DOMAIN']).present?
|
|
190
190
|
config.hosts << ".#{root_domain}"
|
|
191
191
|
end
|
|
@@ -200,7 +200,7 @@ to your customer user model automatically. You then need to **remove the `:valid
|
|
|
200
200
|
manually. `:validatable` validates the user's email uniqueness globally; the concern re-validates
|
|
201
201
|
it in the scope of the tenant instead, so the same email can exist across different tenants.
|
|
202
202
|
|
|
203
|
-
```ruby
|
|
203
|
+
```ruby server/app/models/spree/user.rb
|
|
204
204
|
class Spree::User < Spree.base_class
|
|
205
205
|
include Spree::UserAddress
|
|
206
206
|
include Spree::UserMethods
|
|
@@ -222,7 +222,7 @@ The generator also changes your admin user model's base class from `Spree.base_c
|
|
|
222
222
|
`Spree::Base`. If your `admin_user.rb` exists, this is applied automatically; otherwise make the
|
|
223
223
|
change yourself:
|
|
224
224
|
|
|
225
|
-
```ruby
|
|
225
|
+
```ruby server/app/models/spree/admin_user.rb
|
|
226
226
|
class Spree::AdminUser < Spree.base_class # [!code --]
|
|
227
227
|
class Spree::AdminUser < Spree::Base # [!code ++]
|
|
228
228
|
include Spree::AdminUserMethods
|
|
@@ -61,7 +61,7 @@ npm run test:e2e
|
|
|
61
61
|
|
|
62
62
|
### A `create-spree-app` project's backend
|
|
63
63
|
|
|
64
|
-
A project scaffolded with [`create-spree-app`](../../create-spree-app/quickstart.md) has its customizable Spree in `
|
|
64
|
+
A project scaffolded with [`create-spree-app`](../../create-spree-app/quickstart.md) has its customizable Spree in `server/` (built from `server/Dockerfile`) and this storefront in `apps/storefront/`. Build that backend into a local image and point the suite at it — this is what tests the storefront against the **exact Spree you deploy**, extensions and all:
|
|
65
65
|
|
|
66
66
|
```bash
|
|
67
67
|
# From the project root — build the customized backend image
|
|
@@ -74,7 +74,7 @@ npm run test:e2e
|
|
|
74
74
|
npm run e2e:down
|
|
75
75
|
```
|
|
76
76
|
|
|
77
|
-
> **NOTE:** New `create-spree-app` projects wire this into the generated storefront CI workflow automatically — the workflow builds `
|
|
77
|
+
> **NOTE:** New `create-spree-app` projects wire this into the generated storefront CI workflow automatically — the workflow builds `server/Dockerfile` and runs the storefront E2E against that image rather than stock Spree.
|
|
78
78
|
|
|
79
79
|
### Interactive / manual
|
|
80
80
|
|