Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow setting a billing address on the subscription #119

Merged
merged 9 commits into from
Jun 17, 2020
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class SolidusSubscriptions::Api::V1::SubscriptionsController < Spree::Api::BaseC

def update
if @subscription.update(subscription_params)
render json: @subscription.to_json(include: [:line_items, :shipping_address])
render json: @subscription.to_json(include: [:line_items, :shipping_address, :billing_address])
else
render json: @subscription.errors.to_json, status: 422
end
Expand Down Expand Up @@ -36,7 +36,8 @@ def load_subscription
def subscription_params
params.require(:subscription).permit(
line_items_attributes: line_item_attributes,
shipping_address_attributes: Spree::PermittedAttributes.address_attributes
shipping_address_attributes: Spree::PermittedAttributes.address_attributes,
billing_address_attributes: Spree::PermittedAttributes.address_attributes,
)
end

Expand Down
12 changes: 8 additions & 4 deletions app/controllers/spree/admin/subscriptions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,11 @@ def index
end

def new
@subscription.line_items.new
@subscription.build_shipping_address unless @subscription.shipping_address
prepare_form
end

def edit
@subscription.line_items.new
@subscription.build_shipping_address unless @subscription.shipping_address
prepare_form
end

def cancel
Expand Down Expand Up @@ -70,6 +68,12 @@ def model_class
def location_after_save
edit_object_url(@subscription)
end

def prepare_form
@subscription.line_items.new
@subscription.build_shipping_address unless @subscription.shipping_address
@subscription.build_billing_address unless @subscription.billing_address
end
end
end
end
1 change: 1 addition & 0 deletions app/models/solidus_subscriptions/line_item.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ def interval
def dummy_order
order = spree_line_item ? spree_line_item.order.dup : ::Spree::Order.create
order.ship_address = subscription.shipping_address || subscription.user.ship_address if subscription
order.bill_address = subscription.billing_address || subscription.user.bill_address if subscription

order.freeze
end
Expand Down
2 changes: 2 additions & 0 deletions app/models/solidus_subscriptions/subscription.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ class Subscription < ActiveRecord::Base
has_many :installments, class_name: 'SolidusSubscriptions::Installment'
belongs_to :store, class_name: '::Spree::Store'
belongs_to :shipping_address, class_name: '::Spree::Address', optional: true
belongs_to :billing_address, class_name: '::Spree::Address', optional: true

validates :user, presence: :true
validates :skip_count, :successive_skip_count, presence: true, numericality: { greater_than_or_equal_to: 0 }
validates :interval_length, numericality: { greater_than: 0 }

accepts_nested_attributes_for :shipping_address
accepts_nested_attributes_for :billing_address
accepts_nested_attributes_for :line_items, allow_destroy: true, reject_if: -> (p) { p[:quantity].blank? }

# The following methods are delegated to the associated
Expand Down
14 changes: 12 additions & 2 deletions app/services/solidus_subscriptions/checkout.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,14 @@ def checkout
apply_promotions

order.checkout_steps[0...-1].each do
order.ship_address = ship_address if order.state == "address"
create_payment if order.state == "payment"
case order.state
when "address"
order.ship_address = ship_address
order.bill_address = bill_address
when "payment"
create_payment
end

order.next!
end

Expand Down Expand Up @@ -113,6 +119,10 @@ def ship_address
subscription.shipping_address || user.ship_address
end

def bill_address
subscription.billing_address || user.bill_address
end

def active_card
user.wallet.default_wallet_payment_source.payment_source
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ def activate(subscription_line_items)
line_items: subscription_line_items,
store: order.store,
shipping_address: order.ship_address,
billing_address: order.bill_address,
**configuration.to_h
}

Expand Down
33 changes: 24 additions & 9 deletions app/views/spree/admin/subscriptions/_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,32 @@
</div>
</fieldset>

<fieldset class="no-border-bottom">
<legend>Shipping Address</legend>
<div class="row">
<div class="col-6">
<fieldset class="no-border-bottom">
<legend align="center"><%= t('spree.shipping_address') %></legend>

<div class="js-customer-details">
<div class="js-shipping-address">
<%= f.fields_for :shipping_address do |sa_form| %>
<%= render partial: 'spree/admin/shared/address_form', locals: { f: sa_form, type: "shipping" } %>
<% end %>
</div>
<div class="js-customer-details">
<div class="js-shipping-address">
<%= f.fields_for :shipping_address do |sa_form| %>
<%= render partial: 'spree/admin/shared/address_form', locals: { f: sa_form, type: "shipping" } %>
<% end %>
</div>
</div>
</fieldset>
</div>
</fieldset>

<div class="col-6">
<fieldset class="no-border-bottom">
<legend align="center"><%= t('spree.billing_address') %></legend>
<div class="js-billing-address">
<%= f.fields_for :billing_address do |ba_form| %>
<%= render partial: 'spree/admin/shared/address_form', locals: { f: ba_form, type: "billing" } %>
<% end %>
</div>
</fieldset>
</div>
</div>

<fieldset>
<legend><%= t('.subscription_line_items') %></legend>
Expand Down
11 changes: 11 additions & 0 deletions db/migrate/20200617102749_add_billing_address_to_subscriptions.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class AddBillingAddressToSubscriptions < ActiveRecord::Migration[5.2]
def change
add_reference(
:solidus_subscriptions_subscriptions,
:billing_address,
type: :integer,
index: { name: :index_subscription_billing_address_id },
foreign_key: { to_table: :spree_addresses }
)
end
end
4 changes: 0 additions & 4 deletions lib/solidus_subscriptions/factories.rb

This file was deleted.

2 changes: 1 addition & 1 deletion lib/solidus_subscriptions/processor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def initialize(users)
def build_jobs
users.map do |user|
installemts_by_address_and_user = installments(user).group_by do |i|
i.subscription.shipping_address_id
[i.subscription.shipping_address_id, i.subscription.billing_address_id]
end

installemts_by_address_and_user.values.each do |grouped_installments|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,14 @@
line_items { build_list :subscription_line_item, 1, *line_item_traits }
end

trait :with_address do
trait :with_shipping_address do
association :shipping_address, factory: :address
end

trait :with_billing_address do
association :billing_address, factory: :address
end

trait :actionable do
with_line_item
actionable_date { Time.zone.now.yesterday.beginning_of_minute }
Expand Down
32 changes: 25 additions & 7 deletions reference/solidus_subscriptions.v1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -115,18 +115,36 @@ paths:
content:
application/json:
schema:
type: object
properties:
subscription:
type: object
allOf:
- type: object
properties:
line_items_attributes:
line_items:
type: array
items:
$ref: '#/components/schemas/SubscriptionLineItem'
shipping_address_attributes:
$ref: '#/components/schemas/SubscriptionLineItemOutput'
shipping_address:
type: object
billing_address:
type: object
- $ref: '#/components/schemas/SubscriptionOutput'
operationId: patch-subscriptions-api-v1-subscriptions-id
requestBody:
content:
application/json:
schema:
type: object
properties:
subscription:
type: object
properties:
line_items_attributes:
type: array
items:
$ref: '#/components/schemas/SubscriptionLineItem'
shipping_address_attributes:
type: object
billing_address_attributes:
type: object
'/subscriptions/api/v1/subscriptions/{id}/activate':
parameters:
- schema:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,16 @@
state_id: address_state.id,
phone: '999-999-999',
zipcode: '10001'
},
billing_address_attributes: {
firstname: 'Ash',
lastname: 'Ketchum',
address1: '1 Rainbow Road',
city: 'Palette Town',
country_id: address_country.id,
state_id: address_state.id,
phone: '999-999-999',
zipcode: '10001'
}
}
end
Expand Down
12 changes: 11 additions & 1 deletion spec/lib/solidus_subscriptions/processor_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,23 @@

context 'the subscriptions have different shipping addresses' do
let!(:sub_to_different_address) do
create(:subscription, :actionable, :with_address, user: user)
create(:subscription, :actionable, :with_shipping_address, user: user)
end

it 'creates an order for each shipping address' do
expect { subject }.to change { Spree::Order.complete.count }.by 2
end
end

context 'the subscriptions have different billing addresses' do
let!(:sub_to_different_address) do
create(:subscription, :actionable, :with_billing_address, user: user)
end

it 'creates an order for each billing address' do
expect { subject }.to change { Spree::Order.complete.count }.by 2
end
end
end

describe '.run' do
Expand Down
18 changes: 14 additions & 4 deletions spec/models/solidus_subscriptions/line_item_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,22 +81,32 @@
end

context 'with an associated subscription' do
context 'the associated subscription has an address' do
context 'the associated subscription has a shipping address' do
let(:line_item) do
create(:subscription_line_item, :with_subscription, subscription_traits: [:with_address])
create(:subscription_line_item, :with_subscription, subscription_traits: [:with_shipping_address])
end

it 'uses the subscription shipping address' do
expect(subject.order.ship_address).to eq line_item.subscription.shipping_address
end

it 'uses the subscription users billing address' do
expect(subject.order.bill_address).to eq line_item.subscription.user.bill_address
end
end

context 'the associated subscription has no address' do
let(:line_item) { create(:subscription_line_item, :with_subscription) }
context 'the associated subscription has a billing address' do
let(:line_item) do
create(:subscription_line_item, :with_subscription, subscription_traits: [:with_billing_address])
end

it 'uses the subscription users shipping address' do
expect(subject.order.ship_address).to eq line_item.subscription.user.ship_address
end

it 'uses the subscription billing address' do
expect(subject.order.bill_address).to eq line_item.subscription.billing_address
end
end
end
end
Expand Down
18 changes: 18 additions & 0 deletions spec/services/solidus_subscriptions/checkout_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,24 @@
end
end

context 'the subscription has a billing address' do
it_behaves_like 'a completed checkout'
let(:billing_address) { create :address }
let(:installment_traits) do
{
subscription_traits: [{
billing_address: billing_address,
user: subscription_user,
line_item_traits: [{ spree_line_item: root_order.line_items.first }]
}]
}
end

it 'ships to the subscription address' do
expect(subject.bill_address).to eq billing_address
end
end

context 'there are multiple associated subscritpion line items' do
it_behaves_like 'a completed checkout' do
let(:quantity) { subscription_line_items.length }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
expect(subject).to have_attributes(
user: user,
shipping_address: subscription_line_item.spree_line_item.order.ship_address,
billing_address: subscription_line_item.spree_line_item.order.bill_address,
interval_length: subscription_line_item.interval_length,
interval_units: subscription_line_item.interval_units,
end_date: subscription_line_item.end_date,
Expand Down
4 changes: 2 additions & 2 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
# in spec/support/ and its subdirectories.
Dir[File.join(File.dirname(__FILE__), 'support/**/*.rb')].each { |f| require f }

# Requires factories defined in lib/solidus_subscriptions/factories.rb
require 'solidus_subscriptions/factories'
# Requires factories defined in lib/solidus_subscriptions/testing_support/factories.rb
require 'solidus_subscriptions/testing_support/factories'

RSpec.configure do |config|
config.infer_spec_type_from_file_location!
Expand Down
2 changes: 0 additions & 2 deletions spec/support/factories.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
require 'solidus_subscriptions/testing_support/factories'

FactoryBot.use_parent_strategy = false