From be55f461d086017c54359c5a89518eec7aab6d32 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley Date: Sun, 23 Nov 2014 19:51:52 +0000 Subject: [PATCH] Report: sales tax on orders --- .../admin/reports_controller_decorator.rb | 34 ++++++++++++- app/models/spree/ability_decorator.rb | 2 +- config/routes.rb | 3 +- lib/open_food_network/sales_tax_report.rb | 49 +++++++++++++++++++ spec/features/admin/reports_spec.rb | 9 ++++ 5 files changed, 94 insertions(+), 3 deletions(-) create mode 100644 lib/open_food_network/sales_tax_report.rb diff --git a/app/controllers/spree/admin/reports_controller_decorator.rb b/app/controllers/spree/admin/reports_controller_decorator.rb index 655d1778dc..cb07e7245e 100644 --- a/app/controllers/spree/admin/reports_controller_decorator.rb +++ b/app/controllers/spree/admin/reports_controller_decorator.rb @@ -6,6 +6,7 @@ require 'open_food_network/order_grouper' require 'open_food_network/customers_report' require 'open_food_network/users_and_enterprises_report' require 'open_food_network/order_cycle_management_report' +require 'open_food_network/sales_tax_report' Spree::Admin::ReportsController.class_eval do @@ -102,6 +103,36 @@ Spree::Admin::ReportsController.class_eval do send_data csv_string, :filename => "orders_and_distributors_#{timestamp}.csv" end end + + def sales_tax + params[:q] = {} unless params[:q] + + if params[:q][:completed_at_gt].blank? + params[:q][:completed_at_gt] = Time.zone.now.beginning_of_month + else + params[:q][:completed_at_gt] = Time.zone.parse(params[:q][:completed_at_gt]).beginning_of_day rescue Time.zone.now.beginning_of_month + end + + if params[:q] && !params[:q][:completed_at_lt].blank? + params[:q][:completed_at_lt] = Time.zone.parse(params[:q][:completed_at_lt]).end_of_day rescue "" + end + params[:q][:meta_sort] ||= "completed_at.desc" + + @search = Spree::Order.complete.not_state(:canceled).managed_by(spree_current_user).search(params[:q]) + orders = @search.result + @distributors = Enterprise.is_distributor.managed_by(spree_current_user) + + @report = OpenFoodNetwork::SalesTaxReport.new orders + unless params[:csv] + render :html => @report + else + csv_string = CSV.generate do |csv| + csv << @report.header + @report.table.each { |row| csv << row } + end + send_data csv_string, :filename => "sales_tax.csv" + end + end def bulk_coop params[:q] = {} unless params[:q] @@ -641,7 +672,8 @@ Spree::Admin::ReportsController.class_eval do :products_and_inventory => {:name => "Products & Inventory", :description => ''}, :sales_total => { :name => "Sales Total", :description => "Sales Total For All Orders" }, :users_and_enterprises => { :name => "Users & Enterprises", :description => "Enterprise Ownership & Status" }, - :order_cycle_management => {:name => "Order Cycle Management", :description => ''} + :order_cycle_management => {:name => "Order Cycle Management", :description => ''}, + :sales_tax => { :name => "Sales Tax", :description => "Sales Tax For Orders" } } # Return only reports the user is authorized to view. reports.select { |action| can? action, :report } diff --git a/app/models/spree/ability_decorator.rb b/app/models/spree/ability_decorator.rb index 9bff908346..145d8310de 100644 --- a/app/models/spree/ability_decorator.rb +++ b/app/models/spree/ability_decorator.rb @@ -153,7 +153,7 @@ class AbilityDecorator end # Reports page - can [:admin, :index, :customers, :orders_and_distributors, :group_buys, :bulk_coop, :payments, :orders_and_fulfillment, :products_and_inventory, :order_cycle_management], :report + can [:admin, :index, :customers, :group_buys, :bulk_coop, :sales_tax, :payments, :orders_and_distributors, :orders_and_fulfillment, :products_and_inventory, :order_cycle_management], :report end diff --git a/config/routes.rb b/config/routes.rb index e7f9f2bba0..401ecbeaf3 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -123,7 +123,8 @@ Spree::Core::Engine.routes.prepend do match '/admin/reports/bulk_coop' => 'admin/reports#bulk_coop', :as => "bulk_coop_admin_reports", :via => [:get, :post] match '/admin/reports/payments' => 'admin/reports#payments', :as => "payments_admin_reports", :via => [:get, :post] match '/admin/reports/orders_and_fulfillment' => 'admin/reports#orders_and_fulfillment', :as => "orders_and_fulfillment_admin_reports", :via => [:get, :post] - match '/admin/reports/users_and_enterprises' => 'admin/reports#users_and_enterprises', :as => "users_and_enterprises_admin_reports", :via => [:get, :post] + match '/admin/reports/users_and_enterprises' => 'admin/reports#users_and_enterprises', :as => "users_and_enterprises_admin_reports", :via => [:get, :post] + match '/admin/reports/sales_tax' => 'admin/reports#sales_tax', :as => "sales_tax_admin_reports", :via => [:get, :post] match '/admin/products/bulk_edit' => 'admin/products#bulk_edit', :as => "bulk_edit_admin_products" match '/admin/orders/bulk_management' => 'admin/orders#bulk_management', :as => "admin_bulk_order_management" match '/admin/reports/products_and_inventory' => 'admin/reports#products_and_inventory', :as => "products_and_inventory_admin_reports", :via => [:get, :post] diff --git a/lib/open_food_network/sales_tax_report.rb b/lib/open_food_network/sales_tax_report.rb new file mode 100644 index 0000000000..b3aa8b5419 --- /dev/null +++ b/lib/open_food_network/sales_tax_report.rb @@ -0,0 +1,49 @@ + +module OpenFoodNetwork + class SalesTaxReport + + def initialize orders + @orders = orders + end + + def header + ["Order number", "Date", "Items", "Items total", "Taxable Items Total", "Sales Tax", + "Delivery Charge", "Tax on Delivery", "Total Tax", "Customer", "Distributor"] + end + + def table + sales_tax_details = [] + @orders.each do |order| + totals = {"items" => 0, "items_total" => 0.0, "taxable_total" => 0.0, "sales_tax" => 0.0} + + order.line_items.each do |line_item| + totals["items"] += line_item.quantity + totals["items_total"] += line_item.price * line_item.quantity + + tax_rate = Spree::TaxRate.find_by_tax_category_id(line_item.variant.product.tax_category_id).andand.amount + + if tax_rate != nil && tax_rate != 0 + totals["taxable_total"] += (line_item.price * line_item.quantity) + totals["sales_tax"] += (line_item.price * line_item.quantity) * tax_rate + end + end + + shipping_cost = order.adjustments.find_by_label("Shipping").andand.amount + shipping_cost = (shipping_cost == nil) ? 0.0 : shipping_cost + shipping_tax = (Spree::Config[:shipment_inc_vat] && shipping_cost != nil) ? shipping_cost * 0.2 : 0.0 + + #config option for charging tax on shipping fee or not? exists, need to set rate... + #calculate additional tax for shipping... + #ignore non-shipping adjustments? any potential issues? + #show payment status? other necessary/useful info? + #check which orders are pulled, and which are filtered out... maybe have a dropdown to make it explicit...? + + sales_tax_details << [order.number, order.created_at, totals["items"], totals["items_total"], + totals["taxable_total"], totals["sales_tax"], shipping_cost, shipping_tax, totals["sales_tax"] + shipping_tax, + order.bill_address.full_name, order.distributor.andand.name] + + end + sales_tax_details + end + end +end diff --git a/spec/features/admin/reports_spec.rb b/spec/features/admin/reports_spec.rb index 0524a6769e..056b9b44b8 100644 --- a/spec/features/admin/reports_spec.rb +++ b/spec/features/admin/reports_spec.rb @@ -98,6 +98,15 @@ feature %q{ page.should have_content 'Payment State' end + + scenario "Sales Tax report" do + login_to_admin_section + click_link 'Reports' + click_link 'Sales Tax' + + page.should have_content 'Total Tax' + page.should have_select 'distributor_id' + end describe "orders & fulfilment reports" do it "loads the report page" do