diff --git a/app/helpers/spree/reports_helper.rb b/app/helpers/spree/reports_helper.rb index f4ecdcea6f..bbc184d800 100644 --- a/app/helpers/spree/reports_helper.rb +++ b/app/helpers/spree/reports_helper.rb @@ -18,6 +18,11 @@ module Spree orders.map { |o| o.shipping_method.andand.name }.uniq end + def xero_report_types + [['Summary', 'summary'], + ['Detailed', 'detailed']] + end + def currency_symbol Spree::Money.currency_symbol end diff --git a/app/views/spree/admin/reports/xero_invoices.html.haml b/app/views/spree/admin/reports/xero_invoices.html.haml index 1ae4e3b279..be58420e13 100644 --- a/app/views/spree/admin/reports/xero_invoices.html.haml +++ b/app/views/spree/admin/reports/xero_invoices.html.haml @@ -1,6 +1,9 @@ = form_for @search, url: spree.xero_invoices_admin_reports_path do |f| = render 'date_range_form', f: f + .row + .four.columns.alpha= label_tag :report_type, "Report Type: " + .four.columns.omega= select_tag :report_type, options_for_select(xero_report_types, params[:report_type]), {include_blank: false, class: "select2 fullwidth"} .row .four.columns.alpha= label_tag nil, "Hub: " .four.columns.omega= f.collection_select(:distributor_id_eq, @distributors, :id, :name, {:include_blank => 'All'}, {:class => "select2 fullwidth"}) diff --git a/lib/open_food_network/xero_invoices_report.rb b/lib/open_food_network/xero_invoices_report.rb index 1a7f7bd636..0839564e28 100644 --- a/lib/open_food_network/xero_invoices_report.rb +++ b/lib/open_food_network/xero_invoices_report.rb @@ -5,7 +5,8 @@ module OpenFoodNetwork @opts = opts. reject { |k, v| v.blank? }. - reverse_merge({invoice_date: Date.today, + reverse_merge({report_type: 'summary', + invoice_date: Date.today, due_date: 2.weeks.from_now.to_date, account_code: 'food sales'}) end @@ -19,7 +20,8 @@ module OpenFoodNetwork @orders.each_with_index do |order, i| invoice_number = invoice_number_for(order, i) - rows += rows_for_order(order, invoice_number, @opts) + rows += detail_rows_for_order(order, invoice_number, @opts) if detail? + rows += summary_rows_for_order(order, invoice_number, @opts) end rows @@ -32,7 +34,14 @@ module OpenFoodNetwork @opts[:initial_invoice_number] ? @opts[:initial_invoice_number].to_i+i : order.number end - def rows_for_order(order, invoice_number, opts) + def detail_rows_for_order(order, invoice_number, opts) + order.line_items.map do |line_item| + detail_row(line_item, invoice_number, opts) + end + end + + + def summary_rows_for_order(order, invoice_number, opts) [ summary_row(order, 'Total untaxable produce (no tax)', total_untaxable_products(order), invoice_number, 'GST Free Income', opts), summary_row(order, 'Total taxable produce (tax inclusive)', total_taxable_products(order), invoice_number, 'GST on Income', opts), @@ -42,7 +51,23 @@ module OpenFoodNetwork ].compact end + def detail_row(line_item, invoice_number, opts) + row(line_item.order, + line_item.variant.product_and_variant_name, + line_item.quantity.to_s, + line_item.price.to_s, + invoice_number, + tax_type(line_item), + opts) + end + + def summary_row(order, description, amount, invoice_number, tax_type, opts={}) + row order, description, '1', amount, invoice_number, tax_type, opts + end + + + def row(order, description, quantity, amount, invoice_number, tax_type, opts={}) return nil if amount == 0 [order.bill_address.full_name, @@ -61,7 +86,7 @@ module OpenFoodNetwork opts[:due_date], '', description, - '1', + quantity, amount, '', opts[:account_code], @@ -100,5 +125,13 @@ module OpenFoodNetwork tax_on_shipping = order.adjustments.shipping.sum(&:included_tax) > 0 tax_on_shipping ? 'GST on Income' : 'GST Free Income' end + + def detail? + @opts[:report_type] == 'detailed' + end + + def tax_type(line_item) + line_item.has_tax? ? 'GST on Income' : 'GST Free Income' + end end end diff --git a/spec/features/admin/reports_spec.rb b/spec/features/admin/reports_spec.rb index b4b5a2318f..18eb3ebc9c 100644 --- a/spec/features/admin/reports_spec.rb +++ b/spec/features/admin/reports_spec.rb @@ -418,11 +418,11 @@ feature %q{ it "shows Xero invoices report" do xero_invoice_table.should match_table [ xero_invoice_header, - xero_invoice_row('Total untaxable produce (no tax)', 12.54, 'GST Free Income'), - xero_invoice_row('Total taxable produce (tax inclusive)', 1500.45, 'GST on Income'), - xero_invoice_row('Total untaxable fees (no tax)', 10.0, 'GST Free Income'), - xero_invoice_row('Total taxable fees (tax inclusive)', 20.0, 'GST on Income'), - xero_invoice_row('Delivery Shipping Cost (tax inclusive)', 100.55, 'GST on Income') + xero_invoice_summary_row('Total untaxable produce (no tax)', 12.54, 'GST Free Income'), + xero_invoice_summary_row('Total taxable produce (tax inclusive)', 1500.45, 'GST on Income'), + xero_invoice_summary_row('Total untaxable fees (no tax)', 10.0, 'GST Free Income'), + xero_invoice_summary_row('Total taxable fees (tax inclusive)', 20.0, 'GST on Income'), + xero_invoice_summary_row('Delivery Shipping Cost (tax inclusive)', 100.55, 'GST on Income') ] end @@ -437,11 +437,29 @@ feature %q{ xero_invoice_table.should match_table [ xero_invoice_header, - xero_invoice_row('Total untaxable produce (no tax)', 12.54, 'GST Free Income', opts), - xero_invoice_row('Total taxable produce (tax inclusive)', 1500.45, 'GST on Income', opts), - xero_invoice_row('Total untaxable fees (no tax)', 10.0, 'GST Free Income', opts), - xero_invoice_row('Total taxable fees (tax inclusive)', 20.0, 'GST on Income', opts), - xero_invoice_row('Delivery Shipping Cost (tax inclusive)', 100.55, 'GST on Income', opts) + xero_invoice_summary_row('Total untaxable produce (no tax)', 12.54, 'GST Free Income', opts), + xero_invoice_summary_row('Total taxable produce (tax inclusive)', 1500.45, 'GST on Income', opts), + xero_invoice_summary_row('Total untaxable fees (no tax)', 10.0, 'GST Free Income', opts), + xero_invoice_summary_row('Total taxable fees (tax inclusive)', 20.0, 'GST on Income', opts), + xero_invoice_summary_row('Delivery Shipping Cost (tax inclusive)', 100.55, 'GST on Income', opts) + ] + end + + it "generates a detailed report" do + select 'Detailed', from: 'report_type' + click_button 'Search' + + opts = {} + + xero_invoice_table.should match_table [ + xero_invoice_header, + xero_invoice_li_row(line_item1), + xero_invoice_li_row(line_item2), + xero_invoice_summary_row('Total untaxable produce (no tax)', 12.54, 'GST Free Income', opts), + xero_invoice_summary_row('Total taxable produce (tax inclusive)', 1500.45, 'GST on Income', opts), + xero_invoice_summary_row('Total untaxable fees (no tax)', 10.0, 'GST Free Income', opts), + xero_invoice_summary_row('Total taxable fees (tax inclusive)', 20.0, 'GST on Income', opts), + xero_invoice_summary_row('Delivery Shipping Cost (tax inclusive)', 100.55, 'GST on Income', opts) ] end @@ -456,11 +474,23 @@ feature %q{ %w(*ContactName EmailAddress POAddressLine1 POAddressLine2 POAddressLine3 POAddressLine4 POCity PORegion POPostalCode POCountry *InvoiceNumber Reference *InvoiceDate *DueDate InventoryItemCode *Description *Quantity *UnitAmount Discount *AccountCode *TaxType TrackingName1 TrackingOption1 TrackingName2 TrackingOption2 Currency BrandingTheme Paid?) end - def xero_invoice_row(description, amount, tax_type, opts={}) + def xero_invoice_summary_row(description, amount, tax_type, opts={}) + xero_invoice_row description, amount, '1', tax_type, opts + end + + def xero_invoice_li_row(line_item, opts={}) + tax_type = line_item.has_tax? ? 'GST on Income' : 'GST Free Income' + xero_invoice_row line_item.variant.product_and_variant_name, line_item.price.to_s, line_item.quantity.to_s, tax_type, opts + end + + def xero_invoice_row(description, amount, quantity, tax_type, opts={}) opts.reverse_merge!({invoice_number: order1.number, invoice_date: '2015-04-26', due_date: '2015-05-10', account_code: 'food sales'}) - ['Customer Name', 'customer@email.com', 'customer l1', '', '', '', 'customer city', 'Victoria', '1234', country.name, opts[:invoice_number], order1.number, opts[:invoice_date], opts[:due_date], '', description, '1', amount.to_s, '', opts[:account_code], tax_type, '', '', '', '', Spree::Config.currency, '', 'N'] + ['Customer Name', 'customer@email.com', 'customer l1', '', '', '', 'customer city', 'Victoria', '1234', country.name, opts[:invoice_number], order1.number, opts[:invoice_date], opts[:due_date], '', + description, + quantity, + amount.to_s, '', opts[:account_code], tax_type, '', '', '', '', Spree::Config.currency, '', 'N'] end end end diff --git a/spec/lib/open_food_network/xero_invoices_report_spec.rb b/spec/lib/open_food_network/xero_invoices_report_spec.rb index 8551d663a8..cc0f305e65 100644 --- a/spec/lib/open_food_network/xero_invoices_report_spec.rb +++ b/spec/lib/open_food_network/xero_invoices_report_spec.rb @@ -12,7 +12,8 @@ module OpenFoodNetwork it "uses defaults when blank params are passed" do report.instance_variable_get(:@opts).should == {invoice_date: Date.civil(2015, 5, 5), due_date: Date.civil(2015, 5, 19), - account_code: 'food sales'} + account_code: 'food sales', + report_type: 'summary'} end end