Skip to content

Commit

Permalink
Add the adjustments index page
Browse files Browse the repository at this point in the history
  • Loading branch information
elia committed Jan 10, 2024
1 parent 8372a98 commit 2d4250d
Show file tree
Hide file tree
Showing 9 changed files with 388 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
# frozen_string_literal: true

class SolidusAdmin::Orders::Show::Adjustments::Index::Component < SolidusAdmin::UI::Pages::Index::Component
def model_class
Spree::Adjustment
end

def back_url
solidus_admin.order_path(@order)
end

def title
t(".title", number: @order.number)
end

NBSP = "&nbsp;".html_safe

def initialize(order:, adjustments:)
@order = order
@adjustments = adjustments
@page = GearedPagination::Recordset.new(adjustments, per_page: adjustments.size).page(1)
end

def batch_actions
[
{
display_name: t(".actions.lock"),
action: solidus_admin.lock_order_adjustments_path(@order),
method: :put,
icon: "lock-line"
},
{
display_name: t(".actions.unlock"),
action: solidus_admin.unlock_order_adjustments_path(@order),
method: :put,
icon: "lock-unlock-line"
},
{
display_name: t(".actions.delete"),
action: spree.admin_order_adjustment_path(@order, '[]'),
method: :delete,
icon: "delete-bin-7-line"
},
]
end

def search_key
:label_cont
end

def search_url
solidus_admin.order_adjustments_path(@order)
end

def columns
[
{
header: :state,
wrap: true,
col: { class: 'w-[calc(5rem+2rem+2.5rem+1px)]' },
data: ->(adjustment) {
if adjustment.finalized?
icon = 'lock-fill'
title = t(".state.locked")
else
icon = 'lock-unlock-line'
title = t(".state.unlocked")
end
icon_tag(icon, class: "w-5 h-5 align-middle") + tag.span(title)
}
},
{
header: :adjustable,
col: { class: 'w-56' },
data: ->(adjustment) {
tag.figure(safe_join([
render(component("ui/thumbnail").for(adjustment.adjustable, class: "basis-10")),
figcaption_for_adjustable(adjustment),
]), class: "flex items-center gap-2")
}
},
{
header: :source,
col: { class: "w-56" },
data: ->(adjustment) {
tag.figure(safe_join([
figcaption_for_source(adjustment),
]), class: "flex items-center gap-2")
}
},
{
header: :amount,
col: { class: 'w-24' },
data: ->(adjustment) { tag.span adjustment.display_amount.to_html, class: "grow text-right whitespace-nowrap" }
},
{
header: tag.span(t(".actions.title"), class: 'sr-only'),
col: { class: 'w-24' },
wrap: false,
data: ->(adjustment) do
actions = []

unless adjustment.source
actions << link_to(

Check warning on line 104 in admin/app/components/solidus_admin/orders/show/adjustments/index/component.rb

View check run for this annotation

Codecov / codecov/patch

admin/app/components/solidus_admin/orders/show/adjustments/index/component.rb#L104

Added line #L104 was not covered by tests
t(".actions.edit"),
spree.edit_admin_order_adjustment_path(@order, adjustment),
class: 'body-link',
)
end

if adjustment.finalized?
actions << link_to(
t(".actions.unlock"),
solidus_admin.unlock_order_adjustments_path(@order, id: adjustment),
"data-turbo-method": :put,
"data-turbo-confirm": t('.confirm'),
class: 'body-link',
)
else
actions << link_to(
t(".actions.lock"),
solidus_admin.lock_order_adjustments_path(@order, id: adjustment),
"data-turbo-method": :put,
"data-turbo-confirm": t('.confirm'),
class: 'body-link',
)
actions << link_to(
t(".actions.delete"),
spree.admin_order_adjustment_path(@order, adjustment),
"data-turbo-method": :delete,
"data-turbo-confirm": t('.confirm'),
class: 'body-link !text-red-500',
)
end

render component('ui/dropdown').new(
direction: :right,
class: 'relative w-fit m-auto',
).with_content(safe_join(actions))
end
},
]
end

def icon_thumbnail(name)
render component("ui/thumbnail").new(src: svg_data_uri(icon_tag(name)))

Check warning on line 146 in admin/app/components/solidus_admin/orders/show/adjustments/index/component.rb

View check run for this annotation

Codecov / codecov/patch

admin/app/components/solidus_admin/orders/show/adjustments/index/component.rb#L146

Added line #L146 was not covered by tests
end

def svg_data_uri(data)
"data:image/svg+xml;base64,#{Base64.strict_encode64(data)}"

Check warning on line 150 in admin/app/components/solidus_admin/orders/show/adjustments/index/component.rb

View check run for this annotation

Codecov / codecov/patch

admin/app/components/solidus_admin/orders/show/adjustments/index/component.rb#L150

Added line #L150 was not covered by tests
end

def figcaption_for_source(adjustment)
return thumbnail_caption(adjustment.label, nil) unless adjustment.source_type

# ["Spree::PromotionAction", nil, "Spree::UnitCancel", "Spree::TaxRate"]
record = adjustment.source
record_class = adjustment.source_type&.constantize
model_name = record_class.model_name.human

case record || record_class
when Spree::TaxRate
detail = link_to("#{model_name}: #{record.zone&.name || t('spree.all_zones')}", spree.edit_admin_tax_rate_path(adjustment.source_id), class: "body-link")

Check warning on line 163 in admin/app/components/solidus_admin/orders/show/adjustments/index/component.rb

View check run for this annotation

Codecov / codecov/patch

admin/app/components/solidus_admin/orders/show/adjustments/index/component.rb#L163

Added line #L163 was not covered by tests
when Spree::PromotionAction
detail = link_to("#{model_name}: #{record.promotion.name}", spree.edit_admin_promotion_path(adjustment.source_id), class: "body-link")

Check warning on line 165 in admin/app/components/solidus_admin/orders/show/adjustments/index/component.rb

View check run for this annotation

Codecov / codecov/patch

admin/app/components/solidus_admin/orders/show/adjustments/index/component.rb#L165

Added line #L165 was not covered by tests
else
detail = "#{model_name}: #{record.display_amount}" if record.respond_to?(:display_amount)
end

thumbnail_caption(adjustment.label, detail)
end

def figcaption_for_adjustable(adjustment)
# ["Spree::LineItem", "Spree::Order", "Spree::Shipment"]
record = adjustment.adjustable
record_class = adjustment.adjustable_type&.constantize

case record || record_class
when Spree::LineItem
variant = record.variant
options_text = variant.options_text.presence

Check warning on line 181 in admin/app/components/solidus_admin/orders/show/adjustments/index/component.rb

View check run for this annotation

Codecov / codecov/patch

admin/app/components/solidus_admin/orders/show/adjustments/index/component.rb#L180-L181

Added lines #L180 - L181 were not covered by tests

description = options_text || variant.sku
detail = link_to(variant.product.name, solidus_admin.product_path(record.variant.product), class: "body-link")

Check warning on line 184 in admin/app/components/solidus_admin/orders/show/adjustments/index/component.rb

View check run for this annotation

Codecov / codecov/patch

admin/app/components/solidus_admin/orders/show/adjustments/index/component.rb#L183-L184

Added lines #L183 - L184 were not covered by tests
when Spree::Order
description = "#{Spree::Order.model_name.human} ##{record.number}"
detail = record.display_total
when Spree::Shipment
description = "#{t('spree.shipment')} ##{record.number}"
detail = link_to(record.shipping_method.name, spree.edit_admin_shipping_method_path(record.shipping_method), class: "body-link")

Check warning on line 190 in admin/app/components/solidus_admin/orders/show/adjustments/index/component.rb

View check run for this annotation

Codecov / codecov/patch

admin/app/components/solidus_admin/orders/show/adjustments/index/component.rb#L189-L190

Added lines #L189 - L190 were not covered by tests
when nil
# noop
else
name_method = [:display_name, :name, :number].find { record.respond_to? _1 } if record
price_method = [:display_amount, :display_total, :display_cost].find { record.respond_to? _1 } if record

Check warning on line 195 in admin/app/components/solidus_admin/orders/show/adjustments/index/component.rb

View check run for this annotation

Codecov / codecov/patch

admin/app/components/solidus_admin/orders/show/adjustments/index/component.rb#L194-L195

Added lines #L194 - L195 were not covered by tests

description = record_class.model_name.human
description = "#{description} - #{record.public_send(name_method)}" if name_method

Check warning on line 198 in admin/app/components/solidus_admin/orders/show/adjustments/index/component.rb

View check run for this annotation

Codecov / codecov/patch

admin/app/components/solidus_admin/orders/show/adjustments/index/component.rb#L197-L198

Added lines #L197 - L198 were not covered by tests

# attempt creating a link
url_options = [:admin, record, :edit, { only_path: true }]
url = begin; spree.url_for(url_options); rescue NoMethodError => e; logger.error(e.to_s); nil end

Check warning on line 202 in admin/app/components/solidus_admin/orders/show/adjustments/index/component.rb

View check run for this annotation

Codecov / codecov/patch

admin/app/components/solidus_admin/orders/show/adjustments/index/component.rb#L201-L202

Added lines #L201 - L202 were not covered by tests

description = link_to(description, url, class: "body-link") if url
detail = record.public_send(price_method) if price_method

Check warning on line 205 in admin/app/components/solidus_admin/orders/show/adjustments/index/component.rb

View check run for this annotation

Codecov / codecov/patch

admin/app/components/solidus_admin/orders/show/adjustments/index/component.rb#L204-L205

Added lines #L204 - L205 were not covered by tests
end

thumbnail_caption(description, detail)
end

def thumbnail_caption(first_line, second_line)
tag.figcaption(safe_join([
tag.div(first_line || NBSP, class: 'text-black body-small whitespace-nowrap text-ellipsis overflow-hidden'),
tag.div(second_line || NBSP, class: 'text-gray-500 body-small whitespace-nowrap text-ellipsis overflow-hidden')
]), class: "flex flex-col gap-0 max-w-[15rem]")
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
en:
title: "Order %{number} / Adjustments"
save: "Save"
discard: "Discard"
none: ""

actions:
title: "Actions"
delete: "Delete"
lock: "Lock"
unlock: "Unlock"
edit: "Edit"

state:
locked: "Locked"
unlocked: "Unlocked"
confirm: "Are you sure?"

totals:
adjustable: "Totals (by Adjustable)"
source: "Totals (by Source)"
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
{ label: t('.taxes'), value: number_to_currency(@order.additional_tax_total) },
{ label: t('.shipping'), value: number_to_currency(@order.shipment_total) },
{ label: link_to(t('.add_promo_code'), '#', class: "body-link"), value: number_to_currency(@order.promo_total) },
{ label: link_to(t('.adjustments'), '#', class: "body-link"), value: number_to_currency(@order.adjustment_total) },
{ label: link_to(t('.adjustments'), solidus_admin.order_adjustments_path(@order), class: "body-link"), value: number_to_currency(@order.adjustment_total) },
{ label: t('.total'), value: number_to_currency(@order.total), class: 'font-semibold' }
]
) %>
Expand Down
55 changes: 55 additions & 0 deletions admin/app/controllers/solidus_admin/adjustments_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# frozen_string_literal: true

class SolidusAdmin::AdjustmentsController < SolidusAdmin::BaseController
before_action :load_order

def index
@adjustments = @order
.all_adjustments
.eligible
.order("adjustable_type ASC, created_at ASC")
.ransack(params[:q])
.result

set_page_and_extract_portion_from(@adjustments)

respond_to do |format|
format.html do
render component('orders/show/adjustments/index').new(
order: @order,
adjustments: @adjustments,
)
end
end
end

def lock
@adjustments = @order.all_adjustments.not_finalized.where(id: params[:id])
@adjustments.each(&:finalize!)
flash[:success] = t('.success')

redirect_to order_adjustments_path(@order), status: :see_other
end

def unlock
@adjustments = @order.all_adjustments.finalized.where(id: params[:id])
@adjustments.each(&:unfinalize!)
flash[:success] = t('.success')

redirect_to order_adjustments_path(@order), status: :see_other
end

def destroy
@adjustments = @order.all_adjustments.where(id: params[:id])
@adjustments.destroy_all
flash[:success] = t('.success')

redirect_to order_adjustments_path(@order), status: :see_other
end

private

def load_order
@order = Spree::Order.find_by!(number: params[:order_id])
end
end
10 changes: 10 additions & 0 deletions admin/config/locales/adjustments.en.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
en:
solidus_admin:
adjustments:
title: "Adjustments"
lock:
success: "Locked successfully"
unlock:
success: "Unlocked successfully"
destroy:
success: "Deleted successfully"
8 changes: 8 additions & 0 deletions admin/config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@
admin_resources :orders, except: [
:destroy, :index
], constraints: ->{ SolidusAdmin::Config.enable_alpha_features? } do
resources :adjustments, only: [:index] do
collection do
delete :destroy
put :lock
put :unlock
end
end

resources :line_items, only: [:destroy, :create, :update]
resource :customer
resource :ship_address, only: [:show, :edit, :update], controller: "addresses", type: "ship"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,14 @@ class SolidusAdmin::Orders::Show::Summary::ComponentPreview < ViewComponent::Pre
include SolidusAdmin::Preview

def overview
order = fake_order(item_total: 340, additional_tax_total: 10, shipment_total: 20, promo_total: 10, adjustment_total: 20)
render_with_template(locals: { order: order })
render_with_template(locals: { order: fake_order(
number: "R123",
item_total: 340,
additional_tax_total: 10,
shipment_total: 20,
promo_total: 10,
adjustment_total: 20
) })
end

# @param item_total [Float]
Expand All @@ -15,29 +21,31 @@ def overview
# @param promo_total [Float]
# @param adjustment_total [Float]
def playground(item_total: 100, additional_tax_total: 10, shipment_total: 5, promo_total: 0, adjustment_total: 0)
fake_order = fake_order(
render current_component.new(order: fake_order(
number: "R123",
item_total: item_total,
additional_tax_total: additional_tax_total,
shipment_total: shipment_total,
promo_total: promo_total,
adjustment_total: adjustment_total
)

render current_component.new(order: fake_order)
))
end

private

def fake_order(item_total:, additional_tax_total:, shipment_total:, promo_total:, adjustment_total:)
order = Spree::Order.new
def fake_order(**attributes)
order = Spree::Order.new(attributes)

attributes.each do |key, value|
order.define_singleton_method(key) { value }
end

order.define_singleton_method(:item_total) { item_total }
order.define_singleton_method(:additional_tax_total) { additional_tax_total }
order.define_singleton_method(:shipment_total) { shipment_total }
order.define_singleton_method(:promo_total) { promo_total }
order.define_singleton_method(:adjustment_total) { adjustment_total }
order.define_singleton_method(:total) {
item_total.to_f + additional_tax_total.to_f + shipment_total.to_f - promo_total.to_f - adjustment_total.to_f
item_total.to_f +
additional_tax_total.to_f +
shipment_total.to_f -
promo_total.to_f -
adjustment_total.to_f
}

order
Expand Down
Loading

0 comments on commit 2d4250d

Please sign in to comment.