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

sales tax totals by order report #10247

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions app/services/order_fees_handler.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# frozen_string_literal: true

class OrderFeesHandler
attr_reader :order, :distributor, :order_cycle
attr_reader :order

delegate :distributor, :order_cycle, to: :order

def initialize(order)
@order = order
@distributor = order.distributor
@order_cycle = order.order_cycle
abdellani marked this conversation as resolved.
Show resolved Hide resolved
end

def recreate_all_fees!
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.row
.alpha.two.columns= label_tag nil, t(:report_producers)
.omega.fourteen.columns= select_tag(:supplier_id_in, options_from_collection_for_select(@data.orders_suppliers, :id, :name, params[:supplier_id_in]), {class: "select2 fullwidth", multiple: true})

.row
.alpha.two.columns= label_tag nil, t(:report_customers_cycle)
.omega.fourteen.columns
= f.select(:order_cycle_id_in, report_order_cycle_options(@data.order_cycles), {selected: params.dig(:q, :order_cycle_id_in)}, {class: "select2 fullwidth", multiple: true})
1 change: 1 addition & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1416,6 +1416,7 @@ en:
payment_methods: Payment Methods Report
delivery: Delivery Report
sales_tax_totals_by_producer: Sales Tax Totals By Producer
sales_tax_totals_by_order: Sales Tax Totals By Order
tax_types: Tax Types
tax_rates: Tax Rates
pack_by_customer: Pack By Customer
Expand Down
3 changes: 2 additions & 1 deletion lib/reporting/reports/list.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ def sales_tax_report_types
[
[i18n_translate("tax_types"), :tax_types],
[i18n_translate("tax_rates"), :tax_rates],
[i18n_translate("sales_tax_totals_by_producer"), :sales_tax_totals_by_producer]
[i18n_translate("sales_tax_totals_by_producer"), :sales_tax_totals_by_producer],
[i18n_translate("sales_tax_totals_by_order"), :sales_tax_totals_by_order]
]
end

Expand Down
194 changes: 194 additions & 0 deletions lib/reporting/reports/sales_tax/sales_tax_totals_by_order.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
# frozen_string_literal: true

# rubocop:disable Metrics/ClassLength
module Reporting
module Reports
module SalesTax
class SalesTaxTotalsByOrder < Base
def search
report_line_items.orders
end

def order_permissions
@order_permissions ||= ::Permissions::Order.new(user, ransack_params)
end

def report_line_items
# Needed to filter by supplier_id
@report_line_items ||= Reporting::LineItems.new(order_permissions, params)
end

def query_result
# We'll group the line items by
# [tax_rate_id, order_id]
orders = report_line_items.list.map(&:order).uniq
orders.flat_map(&join_tax_rate)
.group_by(&group_key)
.map(&change_root_to_order)
end
abdellani marked this conversation as resolved.
Show resolved Hide resolved

def join_tax_rate
proc do |order|
tax_rate_ids = order.all_adjustments.tax.pluck("distinct(originator_id)")
tax_rate_ids << nil if tax_rate_ids.empty?
tax_rate_ids.map do |tax_rate_id|
{
tax_rate_id: tax_rate_id,
order: order
}
end
end
end

def group_key
proc do |hash|
[
hash[:tax_rate_id],
hash[:order].id
]
end
end

def change_root_to_order
proc do |key, value|
[key, value.first[:order]]
end
end

def columns
{
distributor: :distributor,
order_cycle: :order_cycle,
order_number: :order_number,
tax_category: :tax_category,
tax_rate_name: :tax_rate_name,
tax_rate: :tax_rate_amount,
total_excl_tax: :total_excl_tax,
tax: :tax_rate_total,
total_incl_tax: :total_incl_tax,
first_name: :first_name,
last_name: :last_name,
code: :code,
email: :email,
}
end

def columns_format
{
tax_rate: :percentage
}
end

def rules
[
{
group_by: :distributor,
},
{
group_by: :order_cycle,
},
{
group_by: :order_number,
summary_row: proc do |_key, items, _rows|
order = items.first.second
{
total_excl_tax: order.total - order.total_tax,
tax: order.total_tax,
total_incl_tax: order.total,
first_name: order.customer&.first_name,
last_name: order.customer&.last_name,
code: order.customer&.code,
email: order.email
}
abdellani marked this conversation as resolved.
Show resolved Hide resolved
end
}
]
end

def distributor(query_result_row)
order(query_result_row).distributor&.name
end

def order_cycle(query_result_row)
order(query_result_row).order_cycle&.name
end

def order_number(query_result_row)
order(query_result_row).number
end

def tax_category(query_result_row)
tax_rate(query_result_row)&.tax_category&.name
end

def tax_rate_name(query_result_row)
tax_rate(query_result_row)&.name
end

def tax_rate_amount(query_result_row)
tax_rate(query_result_row)&.amount
end

def total_excl_tax(query_result_row)
order(query_result_row).total - order(query_result_row).total_tax
end

def tax_rate_total(query_result_row)
order(query_result_row).all_adjustments
.tax
.where(originator_id: tax_rate_id(query_result_row))
.pluck('sum(amount)').first || 0
end

def total_incl_tax(query_result_row)
order(query_result_row).total -
order(query_result_row).total_tax +
tax_rate_total(query_result_row)
end

def first_name(query_result_row)
order(query_result_row).customer&.first_name
end

def last_name(query_result_row)
order(query_result_row).customer&.last_name
end

def code(query_result_row)
order(query_result_row).customer&.code
end

def email(query_result_row)
order(query_result_row).email
end

def tax_rate(query_result_row)
targeted_tax_rate_id = tax_rate_id(query_result_row)
tax_rates(query_result_row).find do |tax_rate|
tax_rate.id == targeted_tax_rate_id
end
end

def tax_rate_id(query_result_row)
key(query_result_row).first
end

def tax_rates(query_result_row)
order(query_result_row).all_adjustments
.tax
.select("distinct(originator_id)", "originator_type")
.map(&:originator)
end

def key(query_result_row)
query_result_row.first
end

def order(query_result_row)
query_result_row.second
end
end
end
end
end
# rubocop:enable Metrics/ClassLength
24 changes: 24 additions & 0 deletions spec/controllers/admin/reports_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -352,4 +352,28 @@
end
end
end

context "Sales Tax Reports By Order" do
let!(:present_objects) { [orderA1, orderA2, orderB1, orderB2] }
let(:report_type) { :sales_tax_totals_by_order }
context "as an admin" do
before do
controller_login_as_admin
end
it "generates the report" do
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dacook mentioned it somewhere else, but can we have spaces between block here and below as well. I am not sure if it should block the PR so leaving it as a comment.

spree_get :show, report_type: :sales_tax, report_subtype: report_type
expect(response).to have_http_status(:ok)
expect(resulting_orders_prelim).to include(orderA1, orderA2, orderB1, orderB2)
end
end
context "as distributor1" do
before { controller_login_as_enterprise_user [distributor1] }
it "generates the report" do
spree_get :show, report_type: :sales_tax, report_subtype: report_type
expect(response).to have_http_status(:ok)
expect(resulting_orders_prelim).to include(orderA1, orderB1)
expect(resulting_orders_prelim).to_not include(orderA2, orderB2)
end
end
end
end
Loading