Solidus I
Aim
- Identify solidus workflow (version 2.10!)
- Identify some shop and customization needs from a German Shop perspective
- Get used to write jekyll blog posts
Requirements
- Linux System able to run “modern” (as of 2020) Rails tech stack
- tolerance: I write down as I learn
- capacity to forget: solidus will further emancipate from spree and the installation process will change
As this is my first contact with solidus, I can guarantee that next time I would do things different. Nonetheless, I want to keep some notes for me along the way.
Pretext: What I understand about solidus so far
Solidus is an e-commerce (“online shop”) system that you can integrate with your Ruby on Rails web-application.
It is a fork of Spree, which was acquired - I’d call it a “protective fork” but do not know the details.
While it seems possible to “install solidus” as engines and gems into an empty Rails application and have a basic shop running, it is also possible to extend the solidus business logic, or just use some parts in the light of your bigger application. It looks like a pretty big thing.
Step one: Bring up the framework
For playing around we want a solidus shop with the whole shebang, thus instead
of requiring only the frontend, backend or other parts, we grab the solidus
dependency, which will pull in all the other stuff.
We will basically follow the solidus README.
That’s it, we can now fire up the server.
and visit localhost:3000 to see the frontend or localhost:3000/admin to log into the backend with the credentials given in the install step (admin@example.com and test123 by default).
Step Two: Don’t pay
We want to make the default currency Euros and look at a checkout process.
As the scenario is a German shop I want to change the Default currency from $ to € (admin -> Settings -> Store -> Default Currency). While we are there, we can also set the default tax country (“Tax Country for Empty Carts”).
Just under that the frontend language can be changed, but we leave that for now.
It is already time for a test-dive and put we can something in our shopping cart and see that the price is listed in €. However, when we continue to checkout the Billing Adress Form
- requires users to enter a phone number,
- doesnt require users to enter a last name and
- the default address country is the US
– we would like to change all of that.
Billing-Address: Switch off your phone
We want to make the phone number field in addresses optional.
The solidus documentation points us directly to the NoPhone monkey-patch .
However, I had to figure out how to apply this monkey patch. After some
professional help I figured
that the file needs to end on _decorator.rb
(rtfm) to be auto-required.
So, add a file:
# app/models/spree/address/optional_phone_decorator.rb
module Spree::Address::OptionalPhoneDecorator
def require_phone?
false
end
Spree::Address.prepend self
end
In this case the “required” markers in the frontend are already aware that the requiredness is optional (the red asterix next to the form input will disappear on server restart).
Billing-Address: Hi Bill … ?
We want to make the last name field in addresses mandatory.
Apparently, in version 3.0, solidus will replace firstname
and lastname
of
addresses by a single name field, but the current (2.10) backend and frontend
still use both attributes.
For whatever reason, only firstname
is a required attribute - in order to
identify users/addresses and make a valid “contract” (bill) with them we need
both, though. At least I believe that it works like that in the EU.
Therefore, we will add a validation in the Backend and adjust the frontend address form (in contrast to the phone number case above, this is not pre-arranged).
Backend: Address validation for lastname
# app/models/spree/address/mandatory_last_name_decorator.rb
module Spree::Address::MandatoryLastNameDecorator
def self.prepended(base)
base.validates :lastname, presence: true
end
Spree::Address.prepend self
end
Frontend: Address validation for lastname
# Copy the address form
mkdir -p app/views/spree/address/
cp $(bundle show solidus_frontend)/app/views/spree/address/_form.html.erb \
app/views/spree/address
# solidus also has a generator to copy views, something like this:
# bundle exec rails generate solidus:views:override --only \
# address/something
# In that file, add `class: 'required' and `, required: true` to the lastname
# field (around line 10, as an example see the firstname field at line 5)
# Also, add the `field-required` class to the containing div (again, see above.)
This basically reverts this Pull Request: https://github.com/solidusio/solidus/pull/2393
Billing-Address: Adjust default customer location
We want that the default customers billing and shipping address is within Germany.
The form will default to Spree::Country.default
, which we can
influence by modifying config/initializers/spree.rb
# config/initializers/spree.rb add
# ...
config.default_country_iso = 'DE'
# ...
In case you need a different iso code, refer to the docs or look what is already
seeded: rails r 'p Spree::Country.all.to_a'
.
Exclude customers
It’s sad and not fair and we love all our “neighbours” (that includes humans on other continents), but right now we cannot spend resources on intensive regulation, tax and shipping company research.
We want have to restrict billing and shipping addresses to a predefined list of
countries.
Thus we will exclude countries from the list of countries to chose from as shipping and billing address.
Therefore, in the backend navigate to Settings -> Zones and delete “North America”. Reflect.
Now, either create a new zone that includes just the countries that are fitting your business needs and possibilities, or modify the example one (“EU_VAT”).
Afterwards, set the checkout_zone
in config/initializers/spree.rb
:
# config/initializers/spree.rb
#...
config.checkout_zone = 'EU_VAT' # referenced by zone name
#...
Taxes
We need to define the German default tax rates.
In Germany, you’ll probably need two tax items. Specify in Backend -> Settings -> Taxes . As this is vanilla solidus, I do not dive into details here.
Wrapup
So far, most things went relatively smooth - few hours including writing this post. Of course to be compliant we would need a lot more customizations (base prices, gdpr and other legal stuff). Maybe I will look into that later.
If you want to cherry-pick commits or see how the whole codebase looks, I set up a github-repository with relatively clean commits for that.
Having a better idea?
Awesome! Get in contact with me!