From 122a64e4889118ced743c6fc079f1bd54889e5ea Mon Sep 17 00:00:00 2001 From: Ahmed Ejaz Date: Sun, 22 Sep 2024 17:14:55 +0500 Subject: [PATCH 01/20] 12776: add new report option --- config/locales/en.yml | 3 +++ lib/reporting/reports/list.rb | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/config/locales/en.yml b/config/locales/en.yml index 80b5a5e90b3..7f03a407a0b 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1768,6 +1768,7 @@ en: pack_by_customer: Pack By Customer pack_by_supplier: Pack By Supplier pack_by_product: Pack By Product + pay_your_suppliers: Pay your suppliers display: report_is_big: "This report is big and may slow down your device." display_anyway: "Display anyway" @@ -1814,6 +1815,8 @@ en: enterprise_fee_summary: name: "Enterprise Fee Summary" description: "Summary of Enterprise Fees collected" + suppliers: + name: Suppliers enterprise_fees_with_tax_report_by_order: "Enterprise Fees With Tax Report By Order" enterprise_fees_with_tax_report_by_producer: "Enterprise Fees With Tax Report By Producer" errors: diff --git a/lib/reporting/reports/list.rb b/lib/reporting/reports/list.rb index a2dd38efc32..9b8c191d02c 100644 --- a/lib/reporting/reports/list.rb +++ b/lib/reporting/reports/list.rb @@ -22,6 +22,7 @@ def all xero_invoices: xero_report_types, packing: packing_report_types, revenues_by_hub: [], + suppliers: suppliers_report_types, } end @@ -107,6 +108,12 @@ def bulk_coop_report_types ] end + def suppliers_report_types + [ + [i18n_translate(:pay_your_suppliers), :pay_your_suppliers] + ] + end + def bulk_coop_item(key) [I18n.t("order_management.reports.bulk_coop.filters.bulk_coop_#{key}"), key] end From 7cb28fd064ef955c482e60fea0aaff1db7ac2bd5 Mon Sep 17 00:00:00 2001 From: Ahmed Ejaz Date: Sun, 29 Sep 2024 17:31:08 +0500 Subject: [PATCH 02/20] 12776: add supplier report --- .../reports/filters/_suppliers.html.haml | 14 ++ config/locales/en.yml | 12 +- lib/reporting/reports/suppliers/base.rb | 100 +++++++++++++++ .../suppliers/helpers/columns_helper.rb | 121 ++++++++++++++++++ .../helpers/line_items_access_helper.rb | 64 +++++++++ 5 files changed, 310 insertions(+), 1 deletion(-) create mode 100644 app/views/admin/reports/filters/_suppliers.html.haml create mode 100644 lib/reporting/reports/suppliers/base.rb create mode 100644 lib/reporting/reports/suppliers/helpers/columns_helper.rb create mode 100644 lib/reporting/reports/suppliers/helpers/line_items_access_helper.rb diff --git a/app/views/admin/reports/filters/_suppliers.html.haml b/app/views/admin/reports/filters/_suppliers.html.haml new file mode 100644 index 00000000000..1c10ffd6ce7 --- /dev/null +++ b/app/views/admin/reports/filters/_suppliers.html.haml @@ -0,0 +1,14 @@ += render 'admin/reports/date_range_form', f: f + +.row + .alpha.two.columns= label_tag nil, t(:report_hubs) + .omega.fourteen.columns= f.collection_select(:distributor_id_in, @data.orders_distributors, :id, :name, {}, {class: "select2 fullwidth", multiple: true}) + +.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}) \ No newline at end of file diff --git a/config/locales/en.yml b/config/locales/en.yml index 7f03a407a0b..07969c9cd81 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -3174,7 +3174,9 @@ See the %{link} to find out more about %{sitename}'s features and to start using report_print: Print Report report_render_options: Rendering Options report_header_ofn_uid: OFN UID - report_header_order_cycle: Order Cycle + report_header_order_cycle: Order Cycle (OC) + report_header_order_cycle_start_date: OC Start Date + report_header_order_cycle_end_date: OC End Date report_header_user: User report_header_email: Email report_header_status: Status @@ -3195,6 +3197,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using report_header_hub_legal_name: "Hub Legal Name" report_header_hub_contact_name: "Hub Contact Name" report_header_hub_email: "Hub Public Email" + report_header_hub_contact_email: Hub Contact Email report_header_hub_owner_email: Hub Owner Email report_header_hub_phone: "Hub Phone Number" report_header_hub_address_line1: "Hub Address Line 1" @@ -3255,6 +3258,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using report_header_quantity: Quantity report_header_max_quantity: Max Quantity report_header_variant: Variant + report_header_variant_unit_name: Variant Unit Name report_header_variant_value: Variant Value report_header_variant_unit: Variant Unit report_header_total_available: Total available @@ -3266,6 +3270,8 @@ See the %{link} to find out more about %{sitename}'s features and to start using report_header_producer_suburb: Producer Suburb report_header_producer_tax_status: Producer Tax Status report_header_producer_charges_sales_tax?: GST/VAT Registered + report_header_producer_abn_acn: Producer ABN/ACN + report_header_producer_address: Producer Address report_header_unit: Unit report_header_group_buy_unit_quantity: Group Buy Unit Quantity report_header_cost: Cost @@ -3326,7 +3332,11 @@ See the %{link} to find out more about %{sitename}'s features and to start using report_header_total_units: Total Units report_header_sum_max_total: "Sum Max Total" report_header_total_excl_vat: "Total excl. tax (%{currency_symbol})" + report_header_total_fees_excl_vat: "Total fees excl. tax (%{currency_symbol})" + report_header_total_vat_on_fees: "Total tax on fees (%{currency_symbol})" + report_header_total: "Total (%{currency_symbol})" report_header_total_incl_vat: "Total incl. tax (%{currency_symbol})" + report_header_total_excl_vat_and_fees: "Total excl. fees and tax (%{currency_symbol})" report_header_temp_controlled: TempControlled? report_header_is_producer: Producer? report_header_not_confirmed: Not Confirmed diff --git a/lib/reporting/reports/suppliers/base.rb b/lib/reporting/reports/suppliers/base.rb new file mode 100644 index 00000000000..28fa3bc45e0 --- /dev/null +++ b/lib/reporting/reports/suppliers/base.rb @@ -0,0 +1,100 @@ +# frozen_string_literal: true + +module Reporting + module Reports + module Suppliers + class Base < ReportTemplate + include Helpers::ColumnsHelper + + def default_params + { + q: { + completed_at_gt: 1.month.ago.beginning_of_day, + completed_at_lt: 1.day.from_now.beginning_of_day + } + } + end + + def search + report_line_items.orders + end + + def query_result + report_line_items.list(line_item_includes).group_by { |e| + [e.variant_id, e.price, e.order.distributor_id] + }.values + end + + def columns + { + producer:, + producer_address:, + producer_abn_acn:, + email:, + hub:, + hub_address:, + hub_contact_email:, + order_number:, + order_date:, + order_cycle:, + order_cycle_start_date:, + order_cycle_end_date:, + product:, + variant_unit_name:, + quantity:, + total_excl_vat_and_fees:, + total_excl_vat:, + total_fees_excl_vat:, + total_vat_on_fees:, + total_tax:, + total:, + } + end + + def rules + [ + { + group_by: :producer, + header: true, + summary_row: proc do |_key, items| + line_items = items.flatten + + { + total_excl_vat_and_fees: total_excl_vat_and_fees.call(line_items), + total_excl_vat: total_excl_vat.call(line_items), + total_fees_excl_vat: total_fees_excl_vat.call(line_items), + total_vat_on_fees: total_vat_on_fees.call(line_items), + total_tax: total_tax.call(line_items), + total: total.call(line_items), + } + end + } + ] + end + + private + + def order_permissions + return @order_permissions unless @order_permissions.nil? + + @order_permissions = ::Permissions::Order.new(@user, ransack_params) + end + + def report_line_items + @report_line_items ||= Reporting::LineItems.new(order_permissions, params) + end + + def line_item_includes + [{ + order: [ + :distributor, + :adjustments, + { shipments: { shipping_rates: :shipping_method } } + ], + variant: [:product, :supplier] + }] + end + end + end + end +end diff --git a/lib/reporting/reports/suppliers/helpers/columns_helper.rb b/lib/reporting/reports/suppliers/helpers/columns_helper.rb new file mode 100644 index 00000000000..a5bd1002e94 --- /dev/null +++ b/lib/reporting/reports/suppliers/helpers/columns_helper.rb @@ -0,0 +1,121 @@ +# frozen_string_literal: true + +module Reporting + module Reports + module Suppliers + module Helpers + module ColumnsHelper + include LineItemsAccessHelper + + def producer + proc { |line_items| supplier(line_items).name } + end + + def producer_address + proc { |line_items| supplier(line_items).address&.full_address } + end + + def producer_abn_acn + proc do |line_items| + supplier = supplier(line_items) + + supplier.abn.presence || supplier.acn + end + end + + def email + proc { |line_items| supplier(line_items).email_address } + end + + def hub + proc { |line_items| distributor(line_items).name } + end + + def hub_address + proc { |line_items| distributor(line_items).address&.full_address } + end + + def hub_contact_email + proc { |line_items| distributor(line_items).email_address } + end + + def order_number + proc { |line_items| order(line_items).number } + end + + def order_date + proc { |line_items| order(line_items).completed_at.strftime("%d/%m/%Y") } + end + + def order_cycle + proc { |line_items| item_order_cycle(line_items).name } + end + + def order_cycle_start_date + proc { |line_items| item_order_cycle(line_items).orders_open_at.strftime("%d/%m/%Y") } + end + + def order_cycle_end_date + proc { |line_items| item_order_cycle(line_items).orders_close_at.strftime("%d/%m/%Y") } + end + + def product + proc { |line_items| variant(line_items).product.name } + end + + def variant_unit_name + proc { |line_items| variant(line_items).full_name } + end + + def quantity + proc { |line_items| line_items.to_a.sum(&:quantity) } + end + + def total_excl_vat_and_fees + proc do |line_items| + included_tax = adjustments_by_type(line_items, :tax, included: true) + line_items.sum(&:amount) - included_tax + end + end + + def total_excl_vat + proc do |line_items| + total_fees = adjustments_by_type(line_items, :fees) + total_excl_vat_and_fees.call(line_items) + total_fees + end + end + + def total_fees_excl_vat + proc do |line_items| + included_tax = tax_on_fees(line_items, included: true) + adjustments_by_type(line_items, :fees) - included_tax + end + end + + def total_vat_on_fees + proc { |line_items| tax_on_fees(line_items) } + end + + def total_tax + proc do |line_items| + excluded_tax = adjustments_by_type(line_items, :tax) + included_tax = adjustments_by_type(line_items, :tax, included: true) + + excluded_tax + included_tax + end + end + + def total + proc do |line_items| + total_price = total_excl_vat_and_fees.call(line_items) + total_fees = total_fees_excl_vat.call(line_items) + tax = total_tax.call(line_items) + + total_price + total_fees + tax + end + end + end + end + end + end +end diff --git a/lib/reporting/reports/suppliers/helpers/line_items_access_helper.rb b/lib/reporting/reports/suppliers/helpers/line_items_access_helper.rb new file mode 100644 index 00000000000..363989d4419 --- /dev/null +++ b/lib/reporting/reports/suppliers/helpers/line_items_access_helper.rb @@ -0,0 +1,64 @@ +# frozen_string_literal: true + +module Reporting + module Reports + module Suppliers + module Helpers + module LineItemsAccessHelper + def variant(line_items) + line_items.first.variant + end + + def order(line_items) + line_items.first.order + end + + def supplier(line_items) + variant(line_items).supplier + end + + def distributor(line_items) + order(line_items).distributor + end + + def item_order_cycle(line_items) + line_items.first.order_cycle + end + + def adjustments_by_type(line_items, type, included: false) + total_amount = 0.0 + adjustment_type = type == :tax ? 'Spree::TaxRate' : 'EnterpriseFee' + adjustments = line_items.flat_map(&:adjustments) + + adjustments.each do |adjustment| + if adjustment.originator_type == adjustment_type + amount = included == adjustment.included ? adjustment.amount : 0.0 + total_amount += amount + end + end + + total_amount + end + + def tax_on_fees(line_items, included: false) + total_amount = 0.0 + adjustments = line_items.flat_map(&:adjustments) + + adjustments.each do |adjustment| + next unless adjustment.originator_type == 'EnterpriseFee' + + adjustment.adjustments.each do |fee_adjustment| + next unless adjustment.originator_type == 'Spree::TaxRate' + + amount = included == fee_adjustment.included ? fee_adjustment.amount : 0.0 + total_amount += amount + end + end + + total_amount + end + end + end + end + end +end From 4349e42a84a1c090901d265a68dbd5d0b3228730 Mon Sep 17 00:00:00 2001 From: Ahmed Ejaz Date: Tue, 1 Oct 2024 03:31:39 +0500 Subject: [PATCH 03/20] 12776: add specs --- .../pay_your_suppliers_report_spec.rb | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 spec/lib/reports/suppliers/pay_your_suppliers_report_spec.rb diff --git a/spec/lib/reports/suppliers/pay_your_suppliers_report_spec.rb b/spec/lib/reports/suppliers/pay_your_suppliers_report_spec.rb new file mode 100644 index 00000000000..547289ee17c --- /dev/null +++ b/spec/lib/reports/suppliers/pay_your_suppliers_report_spec.rb @@ -0,0 +1,69 @@ +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe "Pay Your Suppliers Report" do + let(:hub) { create(:distributor_enterprise) } + let(:order_cycle) { create(:open_order_cycle, distributors: [hub]) } + let(:product) { order.products.first } + let(:variant) { product.variants.first } + let(:supplier) { variant.supplier } + let(:current_user) { hub.owner } + let!(:order) do + create(:completed_order_with_totals, distributor: hub, order_cycle:, line_items_count: 1) + end + let(:params) { { display_summary_row: true } } + let(:report) { Reporting::Reports::Suppliers::Base.new(current_user, { q: params }) } + let(:report_table_rows) { report.rows } + + context "without fees and taxes" do + it "Generates the report" do + expect(report_table_rows.length).to eq(1) + table_row = report_table_rows.first + + expect(table_row.producer).to eq(supplier.name) + expect(table_row.producer_address).to eq(supplier.address.full_address) + expect(table_row.producer_abn_acn).to eq("none") + expect(table_row.email).to eq("none") + expect(table_row.hub).to eq(hub.name) + expect(table_row.hub_address).to eq(hub.address.full_address) + expect(table_row.hub_contact_email).to eq("none") + expect(table_row.order_number).to eq(order.number) + expect(table_row.order_date).to eq(order.completed_at.strftime("%d/%m/%Y")) + expect(table_row.order_cycle).to eq(order_cycle.name) + expect(table_row.order_cycle_start_date).to eq(order_cycle.orders_open_at.strftime("%d/%m/%Y")) + expect(table_row.order_cycle_end_date).to eq(order_cycle.orders_close_at.strftime("%d/%m/%Y")) + expect(table_row.product).to eq(product.name) + expect(table_row.variant_unit_name).to eq(variant.full_name) + expect(table_row.quantity).to eq(1) + expect(table_row.total_excl_vat_and_fees.to_f).to eq(10.0) + expect(table_row.total_excl_vat.to_f).to eq(10.0) + expect(table_row.total_fees_excl_vat.to_f).to eq(0.0) + expect(table_row.total_vat_on_fees.to_f).to eq(0.0) + expect(table_row.total_tax.to_f).to eq(0.0) + expect(table_row.total.to_f).to eq(10.0) + end + end + + context "with taxes and fees" do + let(:line_item) { order.line_items.first } + let!(:fees_adjustment) do + create(:adjustment, originator_type: "EnterpriseFee", adjustable: line_item, amount: 0.1) + end + let!(:tax_adjustment) do + create(:adjustment, originator_type: "Spree::TaxRate", adjustable: line_item, amount: 0.1) + end + + it "Generates the report" do + expect(report_table_rows.length).to eq(1) + table_row = report_table_rows.first + + expect(table_row.total_excl_vat_and_fees.to_f).to eq(10.0) + expect(table_row.total_excl_vat.to_f).to eq(10.1) + expect(table_row.total_fees_excl_vat.to_f).to eq(0.1) + expect(table_row.total_vat_on_fees.to_f).to eq(0.0) + expect(table_row.total_tax.to_f).to eq(0.1) + expect(table_row.total.to_f).to eq(10.2) + end + end +end From add973f1ff1d351a2d6f5a0ec6380b4c0f95d479 Mon Sep 17 00:00:00 2001 From: Ahmed Ejaz Date: Tue, 1 Oct 2024 03:37:11 +0500 Subject: [PATCH 04/20] 12776: add new line --- app/views/admin/reports/filters/_suppliers.html.haml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/views/admin/reports/filters/_suppliers.html.haml b/app/views/admin/reports/filters/_suppliers.html.haml index 1c10ffd6ce7..14310787d48 100644 --- a/app/views/admin/reports/filters/_suppliers.html.haml +++ b/app/views/admin/reports/filters/_suppliers.html.haml @@ -11,4 +11,5 @@ .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}) \ No newline at end of file + = 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}) + \ No newline at end of file From 13a614a5aa1d5a9f174e728aa35d725ce9571c92 Mon Sep 17 00:00:00 2001 From: Ahmed Ejaz Date: Tue, 1 Oct 2024 03:46:06 +0500 Subject: [PATCH 05/20] fix rubocop lines issue --- lib/reporting/reports/list.rb | 97 +----------------------- lib/reporting/reports/report_types.rb | 104 ++++++++++++++++++++++++++ 2 files changed, 106 insertions(+), 95 deletions(-) create mode 100644 lib/reporting/reports/report_types.rb diff --git a/lib/reporting/reports/list.rb b/lib/reporting/reports/list.rb index 9b8c191d02c..22c23ff52ab 100644 --- a/lib/reporting/reports/list.rb +++ b/lib/reporting/reports/list.rb @@ -3,6 +3,8 @@ module Reporting module Reports class List + include ReportTypes + def self.all new.all end @@ -26,101 +28,6 @@ def all } end - protected - - def orders_and_fulfillment_report_types - [ - [i18n_translate("supplier_totals"), :order_cycle_supplier_totals], - [i18n_translate("supplier_totals_by_distributor"), - :order_cycle_supplier_totals_by_distributor], - [i18n_translate("totals_by_supplier"), :order_cycle_distributor_totals_by_supplier], - [i18n_translate("customer_totals"), :order_cycle_customer_totals] - ] - end - - def products_and_inventory_report_types - [ - [i18n_translate("all_products"), :all_products], - [i18n_translate("inventory"), :inventory, { deprecated: true }], - [i18n_translate("lettuce_share"), :lettuce_share] - ] - end - - def payments_report_types - [ - [I18n.t(:report_payment_by), :payments_by_payment_type], - [I18n.t(:report_itemised_payment), :itemised_payment_totals], - [I18n.t(:report_payment_totals), :payment_totals] - ] - end - - def enterprise_fee_summary - [ - [i18n_translate('enterprise_fee_summary.name'), :fee_summary], - [ - i18n_translate('enterprise_fees_with_tax_report_by_order'), - :enterprise_fees_with_tax_report_by_order - ], - [ - i18n_translate('enterprise_fees_with_tax_report_by_producer'), - :enterprise_fees_with_tax_report_by_producer - ], - ] - end - - def order_cycle_management_report_types - [ - [i18n_translate("payment_methods"), :payment_methods], - [i18n_translate("delivery"), :delivery] - ] - end - - 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_order"), :sales_tax_totals_by_order] - ] - end - - def packing_report_types - [ - [i18n_translate("pack_by_customer"), :customer], - [i18n_translate("pack_by_supplier"), :supplier], - [i18n_translate("pack_by_product"), :product] - ] - end - - def xero_report_types - [ - [I18n.t(:summary), 'summary'], - [I18n.t(:detailed), 'detailed'] - ] - end - - def bulk_coop_report_types - [ - bulk_coop_item(:supplier_report), - bulk_coop_item(:allocation), - bulk_coop_item(:packing_sheets), - bulk_coop_item(:customer_payments) - ] - end - - def suppliers_report_types - [ - [i18n_translate(:pay_your_suppliers), :pay_your_suppliers] - ] - end - - def bulk_coop_item(key) - [I18n.t("order_management.reports.bulk_coop.filters.bulk_coop_#{key}"), key] - end - - def i18n_translate(key) - I18n.t(key, scope: "admin.reports") - end end end end diff --git a/lib/reporting/reports/report_types.rb b/lib/reporting/reports/report_types.rb new file mode 100644 index 00000000000..3ec912c7cfe --- /dev/null +++ b/lib/reporting/reports/report_types.rb @@ -0,0 +1,104 @@ +# frozen_string_literal: true + +module Reporting + module Reports + module ReportTypes + + protected + + def orders_and_fulfillment_report_types + [ + [i18n_translate("supplier_totals"), :order_cycle_supplier_totals], + [i18n_translate("supplier_totals_by_distributor"), + :order_cycle_supplier_totals_by_distributor], + [i18n_translate("totals_by_supplier"), :order_cycle_distributor_totals_by_supplier], + [i18n_translate("customer_totals"), :order_cycle_customer_totals] + ] + end + + def products_and_inventory_report_types + [ + [i18n_translate("all_products"), :all_products], + [i18n_translate("inventory"), :inventory, { deprecated: true }], + [i18n_translate("lettuce_share"), :lettuce_share] + ] + end + + def payments_report_types + [ + [I18n.t(:report_payment_by), :payments_by_payment_type], + [I18n.t(:report_itemised_payment), :itemised_payment_totals], + [I18n.t(:report_payment_totals), :payment_totals] + ] + end + + def enterprise_fee_summary + [ + [i18n_translate('enterprise_fee_summary.name'), :fee_summary], + [ + i18n_translate('enterprise_fees_with_tax_report_by_order'), + :enterprise_fees_with_tax_report_by_order + ], + [ + i18n_translate('enterprise_fees_with_tax_report_by_producer'), + :enterprise_fees_with_tax_report_by_producer + ], + ] + end + + def order_cycle_management_report_types + [ + [i18n_translate("payment_methods"), :payment_methods], + [i18n_translate("delivery"), :delivery] + ] + end + + 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_order"), :sales_tax_totals_by_order] + ] + end + + def packing_report_types + [ + [i18n_translate("pack_by_customer"), :customer], + [i18n_translate("pack_by_supplier"), :supplier], + [i18n_translate("pack_by_product"), :product] + ] + end + + def xero_report_types + [ + [I18n.t(:summary), 'summary'], + [I18n.t(:detailed), 'detailed'] + ] + end + + def bulk_coop_report_types + [ + bulk_coop_item(:supplier_report), + bulk_coop_item(:allocation), + bulk_coop_item(:packing_sheets), + bulk_coop_item(:customer_payments) + ] + end + + def suppliers_report_types + [ + [i18n_translate(:pay_your_suppliers), :pay_your_suppliers] + ] + end + + def bulk_coop_item(key) + [I18n.t("order_management.reports.bulk_coop.filters.bulk_coop_#{key}"), key] + end + + def i18n_translate(key) + I18n.t(key, scope: "admin.reports") + end + end + end +end From 77f9c6587cd54598321bc3f7cf671a274ccf1ac3 Mon Sep 17 00:00:00 2001 From: Ahmed Ejaz Date: Tue, 1 Oct 2024 03:51:00 +0500 Subject: [PATCH 06/20] fix specs --- app/views/admin/reports/filters/_suppliers.html.haml | 1 - config/locales/en.yml | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/app/views/admin/reports/filters/_suppliers.html.haml b/app/views/admin/reports/filters/_suppliers.html.haml index 14310787d48..0a9963544ff 100644 --- a/app/views/admin/reports/filters/_suppliers.html.haml +++ b/app/views/admin/reports/filters/_suppliers.html.haml @@ -12,4 +12,3 @@ .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}) - \ No newline at end of file diff --git a/config/locales/en.yml b/config/locales/en.yml index 07969c9cd81..7bff667b078 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -3174,7 +3174,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using report_print: Print Report report_render_options: Rendering Options report_header_ofn_uid: OFN UID - report_header_order_cycle: Order Cycle (OC) + report_header_order_cycle: Order Cycle report_header_order_cycle_start_date: OC Start Date report_header_order_cycle_end_date: OC End Date report_header_user: User From 654263a823d6c2a92f4560692064a3c01c9e1125 Mon Sep 17 00:00:00 2001 From: Ahmed Ejaz Date: Mon, 7 Oct 2024 15:07:42 +0500 Subject: [PATCH 07/20] add systems spec --- app/models/spree/ability.rb | 2 +- lib/reporting/reports/list.rb | 1 - lib/reporting/reports/report_types.rb | 1 - .../pay_your_suppliers_report_spec.rb | 4 +- .../admin/reports/pay_your_suppliers_spec.rb | 82 +++++++++++++++++++ 5 files changed, 86 insertions(+), 4 deletions(-) create mode 100644 spec/system/admin/reports/pay_your_suppliers_spec.rb diff --git a/app/models/spree/ability.rb b/app/models/spree/ability.rb index 3233e58c6d9..572efddd8ce 100644 --- a/app/models/spree/ability.rb +++ b/app/models/spree/ability.rb @@ -244,7 +244,7 @@ def add_product_management_abilities(user) can [:admin, :index, :show, :create], ::Admin::ReportsController can [:admin, :show, :create, :customers, :orders_and_distributors, :group_buys, :payments, :orders_and_fulfillment, :products_and_inventory, :order_cycle_management, - :packing, :enterprise_fee_summary, :bulk_coop], :report + :packing, :enterprise_fee_summary, :bulk_coop, :suppliers], :report end def add_order_cycle_management_abilities(user) diff --git a/lib/reporting/reports/list.rb b/lib/reporting/reports/list.rb index 22c23ff52ab..95d5b38abfa 100644 --- a/lib/reporting/reports/list.rb +++ b/lib/reporting/reports/list.rb @@ -27,7 +27,6 @@ def all suppliers: suppliers_report_types, } end - end end end diff --git a/lib/reporting/reports/report_types.rb b/lib/reporting/reports/report_types.rb index 3ec912c7cfe..d68225722ea 100644 --- a/lib/reporting/reports/report_types.rb +++ b/lib/reporting/reports/report_types.rb @@ -3,7 +3,6 @@ module Reporting module Reports module ReportTypes - protected def orders_and_fulfillment_report_types diff --git a/spec/lib/reports/suppliers/pay_your_suppliers_report_spec.rb b/spec/lib/reports/suppliers/pay_your_suppliers_report_spec.rb index 547289ee17c..4ad3e944a57 100644 --- a/spec/lib/reports/suppliers/pay_your_suppliers_report_spec.rb +++ b/spec/lib/reports/suppliers/pay_your_suppliers_report_spec.rb @@ -31,7 +31,9 @@ expect(table_row.order_number).to eq(order.number) expect(table_row.order_date).to eq(order.completed_at.strftime("%d/%m/%Y")) expect(table_row.order_cycle).to eq(order_cycle.name) - expect(table_row.order_cycle_start_date).to eq(order_cycle.orders_open_at.strftime("%d/%m/%Y")) + expect(table_row.order_cycle_start_date).to eq( + order_cycle.orders_open_at.strftime("%d/%m/%Y") + ) expect(table_row.order_cycle_end_date).to eq(order_cycle.orders_close_at.strftime("%d/%m/%Y")) expect(table_row.product).to eq(product.name) expect(table_row.variant_unit_name).to eq(variant.full_name) diff --git a/spec/system/admin/reports/pay_your_suppliers_spec.rb b/spec/system/admin/reports/pay_your_suppliers_spec.rb new file mode 100644 index 00000000000..09a2d470fcd --- /dev/null +++ b/spec/system/admin/reports/pay_your_suppliers_spec.rb @@ -0,0 +1,82 @@ +# frozen_string_literal: true + +require "system_helper" + +RSpec.describe "Pay Your Suppliers Report" do + include ReportsHelper + + let(:hub) { create(:distributor_enterprise) } + let(:order_cycle) { create(:open_order_cycle, distributors: [hub]) } + let(:product) { order.products.first } + let(:variant) { product.variants.first } + let(:supplier) { variant.supplier } + let(:current_user) { hub.owner } + let!(:order) do + create(:completed_order_with_totals, distributor: hub, order_cycle:, line_items_count: 1) + end + let(:params) { { display_summary_row: true } } + let(:report) { Reporting::Reports::Suppliers::Base.new(current_user, { q: params }) } + let(:report_table_rows) { report.rows } + + before do + login_as current_user + visit admin_reports_path + end + + context "on Reports page" do + it "should generate 'Pay Your Suppliers' report" do + click_on 'Pay your suppliers' + expect(page).to have_button("Go") + run_report + + expect(page.find("table.report__table thead tr").text).to have_content([ + "Producer", + "Producer Address", + "Producer ABN/ACN", + "Email", + "Hub", + "Hub Address", + "Hub Contact Email", + "Order number", + "Order date", + "Order Cycle", + "OC Start Date", + "OC End Date", + "Product", + "Variant Unit Name", + "Quantity", + "Total excl. fees and tax ($)", + "Total excl. tax ($)", + "Total fees excl. tax ($)", + "Total tax on fees ($)", + "Total Tax ($)", + "Total ($)" + ].join(" ")) + + line = page.find('table.report__table tbody tr').text + expect(line).to have_content([ + supplier.name, + supplier.address.full_address, + "none", + "none", + hub.name, + hub.address.full_address, + "none", + order.number, + order.completed_at.strftime("%d/%m/%Y"), + order_cycle.name, + order_cycle.orders_open_at.strftime("%d/%m/%Y"), + order_cycle.orders_close_at.strftime("%d/%m/%Y"), + product.name, + variant.full_name, + '1', + '10.0', + '10.0', + '0.0', + '0.0', + '0.0', + '10.0', + ].compact.join(" ")) + end + end +end From 458c8f7608daf22efdb78525081370807d3b9622 Mon Sep 17 00:00:00 2001 From: Ahmed Ejaz Date: Tue, 8 Oct 2024 23:54:47 +0500 Subject: [PATCH 08/20] Update lib/reporting/reports/suppliers/helpers/columns_helper.rb Co-authored-by: David Cook --- lib/reporting/reports/suppliers/helpers/columns_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/reporting/reports/suppliers/helpers/columns_helper.rb b/lib/reporting/reports/suppliers/helpers/columns_helper.rb index a5bd1002e94..7db71714e75 100644 --- a/lib/reporting/reports/suppliers/helpers/columns_helper.rb +++ b/lib/reporting/reports/suppliers/helpers/columns_helper.rb @@ -19,7 +19,7 @@ def producer_abn_acn proc do |line_items| supplier = supplier(line_items) - supplier.abn.presence || supplier.acn + [supplier.abn, supplier.acn].compact_blank.join("/") end end From 68c0d98736b538064b3260b95f18e377c521b2a7 Mon Sep 17 00:00:00 2001 From: Ahmed Ejaz Date: Wed, 9 Oct 2024 00:39:54 +0500 Subject: [PATCH 09/20] add slash for abn acn --- lib/reporting/reports/suppliers/helpers/columns_helper.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/reporting/reports/suppliers/helpers/columns_helper.rb b/lib/reporting/reports/suppliers/helpers/columns_helper.rb index 7db71714e75..d7a56e78e53 100644 --- a/lib/reporting/reports/suppliers/helpers/columns_helper.rb +++ b/lib/reporting/reports/suppliers/helpers/columns_helper.rb @@ -18,8 +18,8 @@ def producer_address def producer_abn_acn proc do |line_items| supplier = supplier(line_items) - - [supplier.abn, supplier.acn].compact_blank.join("/") + # return nil if both abn and acn are nil so that it can be converted to "none" + [supplier.abn, supplier.acn].compact_blank.join("/").presence end end From ec0d2d346b2da30e9f4972ffcdc6e6d82d94ee4b Mon Sep 17 00:00:00 2001 From: Ahmed Ejaz Date: Wed, 9 Oct 2024 00:56:57 +0500 Subject: [PATCH 10/20] use to_date for locale based formating --- lib/reporting/reports/suppliers/helpers/columns_helper.rb | 6 +++--- .../lib/reports/suppliers/pay_your_suppliers_report_spec.rb | 6 +++--- spec/system/admin/reports/pay_your_suppliers_spec.rb | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/reporting/reports/suppliers/helpers/columns_helper.rb b/lib/reporting/reports/suppliers/helpers/columns_helper.rb index d7a56e78e53..eaa1e840063 100644 --- a/lib/reporting/reports/suppliers/helpers/columns_helper.rb +++ b/lib/reporting/reports/suppliers/helpers/columns_helper.rb @@ -44,7 +44,7 @@ def order_number end def order_date - proc { |line_items| order(line_items).completed_at.strftime("%d/%m/%Y") } + proc { |line_items| order(line_items).completed_at.to_date } end def order_cycle @@ -52,11 +52,11 @@ def order_cycle end def order_cycle_start_date - proc { |line_items| item_order_cycle(line_items).orders_open_at.strftime("%d/%m/%Y") } + proc { |line_items| item_order_cycle(line_items).orders_open_at.to_date } end def order_cycle_end_date - proc { |line_items| item_order_cycle(line_items).orders_close_at.strftime("%d/%m/%Y") } + proc { |line_items| item_order_cycle(line_items).orders_close_at.to_date } end def product diff --git a/spec/lib/reports/suppliers/pay_your_suppliers_report_spec.rb b/spec/lib/reports/suppliers/pay_your_suppliers_report_spec.rb index 4ad3e944a57..fc0370ff004 100644 --- a/spec/lib/reports/suppliers/pay_your_suppliers_report_spec.rb +++ b/spec/lib/reports/suppliers/pay_your_suppliers_report_spec.rb @@ -29,12 +29,12 @@ expect(table_row.hub_address).to eq(hub.address.full_address) expect(table_row.hub_contact_email).to eq("none") expect(table_row.order_number).to eq(order.number) - expect(table_row.order_date).to eq(order.completed_at.strftime("%d/%m/%Y")) + expect(table_row.order_date).to eq(order.completed_at.to_date.to_s) expect(table_row.order_cycle).to eq(order_cycle.name) expect(table_row.order_cycle_start_date).to eq( - order_cycle.orders_open_at.strftime("%d/%m/%Y") + order_cycle.orders_open_at.to_date.to_s ) - expect(table_row.order_cycle_end_date).to eq(order_cycle.orders_close_at.strftime("%d/%m/%Y")) + expect(table_row.order_cycle_end_date).to eq(order_cycle.orders_close_at.to_date.to_s) expect(table_row.product).to eq(product.name) expect(table_row.variant_unit_name).to eq(variant.full_name) expect(table_row.quantity).to eq(1) diff --git a/spec/system/admin/reports/pay_your_suppliers_spec.rb b/spec/system/admin/reports/pay_your_suppliers_spec.rb index 09a2d470fcd..8bc1760c9bc 100644 --- a/spec/system/admin/reports/pay_your_suppliers_spec.rb +++ b/spec/system/admin/reports/pay_your_suppliers_spec.rb @@ -63,10 +63,10 @@ hub.address.full_address, "none", order.number, - order.completed_at.strftime("%d/%m/%Y"), + order.completed_at.to_date.to_s, order_cycle.name, - order_cycle.orders_open_at.strftime("%d/%m/%Y"), - order_cycle.orders_close_at.strftime("%d/%m/%Y"), + order_cycle.orders_open_at.to_date.to_s, + order_cycle.orders_close_at.to_date.to_s, product.name, variant.full_name, '1', From 1fbdf252967d337bd82cdf2b45c571702c25ab8e Mon Sep 17 00:00:00 2001 From: Ahmed Ejaz Date: Wed, 9 Oct 2024 02:18:19 +0500 Subject: [PATCH 11/20] 12776: fix missing order numbers --- lib/reporting/reports/suppliers/base.rb | 26 ++++---- .../suppliers/helpers/columns_helper.rb | 62 +++++++++---------- .../helpers/line_items_access_helper.rb | 29 +++++---- 3 files changed, 58 insertions(+), 59 deletions(-) diff --git a/lib/reporting/reports/suppliers/base.rb b/lib/reporting/reports/suppliers/base.rb index 28fa3bc45e0..84938e3b34f 100644 --- a/lib/reporting/reports/suppliers/base.rb +++ b/lib/reporting/reports/suppliers/base.rb @@ -20,9 +20,7 @@ def search end def query_result - report_line_items.list(line_item_includes).group_by { |e| - [e.variant_id, e.price, e.order.distributor_id] - }.values + report_line_items.list(line_item_includes) end def columns @@ -56,17 +54,19 @@ def rules { group_by: :producer, header: true, - summary_row: proc do |_key, items| - line_items = items.flatten + summary_row: proc do |_key, line_items| + summary_hash = Hash.new(0) - { - total_excl_vat_and_fees: total_excl_vat_and_fees.call(line_items), - total_excl_vat: total_excl_vat.call(line_items), - total_fees_excl_vat: total_fees_excl_vat.call(line_items), - total_vat_on_fees: total_vat_on_fees.call(line_items), - total_tax: total_tax.call(line_items), - total: total.call(line_items), - } + line_items.each do |line_item| + summary_hash[:total_excl_vat_and_fees] += total_excl_vat_and_fees.call(line_item) + summary_hash[:total_excl_vat] += total_excl_vat.call(line_item) + summary_hash[:total_fees_excl_vat] += total_fees_excl_vat.call(line_item) + summary_hash[:total_vat_on_fees] += total_vat_on_fees.call(line_item) + summary_hash[:total_tax] += total_tax.call(line_item) + summary_hash[:total] += total.call(line_item) + end + + summary_hash end } ] diff --git a/lib/reporting/reports/suppliers/helpers/columns_helper.rb b/lib/reporting/reports/suppliers/helpers/columns_helper.rb index eaa1e840063..d91bd40f9a5 100644 --- a/lib/reporting/reports/suppliers/helpers/columns_helper.rb +++ b/lib/reporting/reports/suppliers/helpers/columns_helper.rb @@ -8,11 +8,11 @@ module ColumnsHelper include LineItemsAccessHelper def producer - proc { |line_items| supplier(line_items).name } + proc { |line_item| supplier(line_item).name } end def producer_address - proc { |line_items| supplier(line_items).address&.full_address } + proc { |line_item| supplier(line_item).address&.full_address } end def producer_abn_acn @@ -24,92 +24,92 @@ def producer_abn_acn end def email - proc { |line_items| supplier(line_items).email_address } + proc { |line_item| supplier(line_item).email_address } end def hub - proc { |line_items| distributor(line_items).name } + proc { |line_item| distributor(line_item).name } end def hub_address - proc { |line_items| distributor(line_items).address&.full_address } + proc { |line_item| distributor(line_item).address&.full_address } end def hub_contact_email - proc { |line_items| distributor(line_items).email_address } + proc { |line_item| distributor(line_item).email_address } end def order_number - proc { |line_items| order(line_items).number } + proc { |line_item| order(line_item).number } end def order_date - proc { |line_items| order(line_items).completed_at.to_date } + proc { |line_item| order(line_item).completed_at.to_date } end def order_cycle - proc { |line_items| item_order_cycle(line_items).name } + proc { |line_item| item_order_cycle(line_item).name } end def order_cycle_start_date - proc { |line_items| item_order_cycle(line_items).orders_open_at.to_date } + proc { |line_item| item_order_cycle(line_item).orders_open_at.to_date } end def order_cycle_end_date - proc { |line_items| item_order_cycle(line_items).orders_close_at.to_date } + proc { |line_item| item_order_cycle(line_item).orders_close_at.to_date } end def product - proc { |line_items| variant(line_items).product.name } + proc { |line_item| variant(line_item).product.name } end def variant_unit_name - proc { |line_items| variant(line_items).full_name } + proc { |line_item| variant(line_item).full_name } end def quantity - proc { |line_items| line_items.to_a.sum(&:quantity) } + proc { |line_item| line_item.quantity } end def total_excl_vat_and_fees - proc do |line_items| - included_tax = adjustments_by_type(line_items, :tax, included: true) - line_items.sum(&:amount) - included_tax + proc do |line_item| + included_tax = adjustments_by_type(line_item, :tax, included: true) + line_item.amount - included_tax end end def total_excl_vat - proc do |line_items| - total_fees = adjustments_by_type(line_items, :fees) - total_excl_vat_and_fees.call(line_items) + total_fees + proc do |line_item| + total_fees = adjustments_by_type(line_item, :fees) + total_excl_vat_and_fees.call(line_item) + total_fees end end def total_fees_excl_vat - proc do |line_items| - included_tax = tax_on_fees(line_items, included: true) - adjustments_by_type(line_items, :fees) - included_tax + proc do |line_item| + included_tax = tax_on_fees(line_item, included: true) + adjustments_by_type(line_item, :fees) - included_tax end end def total_vat_on_fees - proc { |line_items| tax_on_fees(line_items) } + proc { |line_item| tax_on_fees(line_item) } end def total_tax - proc do |line_items| - excluded_tax = adjustments_by_type(line_items, :tax) - included_tax = adjustments_by_type(line_items, :tax, included: true) + proc do |line_item| + excluded_tax = adjustments_by_type(line_item, :tax) + included_tax = adjustments_by_type(line_item, :tax, included: true) excluded_tax + included_tax end end def total - proc do |line_items| - total_price = total_excl_vat_and_fees.call(line_items) - total_fees = total_fees_excl_vat.call(line_items) - tax = total_tax.call(line_items) + proc do |line_item| + total_price = total_excl_vat_and_fees.call(line_item) + total_fees = total_fees_excl_vat.call(line_item) + tax = total_tax.call(line_item) total_price + total_fees + tax end diff --git a/lib/reporting/reports/suppliers/helpers/line_items_access_helper.rb b/lib/reporting/reports/suppliers/helpers/line_items_access_helper.rb index 363989d4419..26318f17164 100644 --- a/lib/reporting/reports/suppliers/helpers/line_items_access_helper.rb +++ b/lib/reporting/reports/suppliers/helpers/line_items_access_helper.rb @@ -5,31 +5,30 @@ module Reports module Suppliers module Helpers module LineItemsAccessHelper - def variant(line_items) - line_items.first.variant + def variant(line_item) + line_item.variant end - def order(line_items) - line_items.first.order + def order(line_item) + line_item.order end - def supplier(line_items) - variant(line_items).supplier + def supplier(line_item) + variant(line_item).supplier end - def distributor(line_items) - order(line_items).distributor + def distributor(line_item) + order(line_item).distributor end - def item_order_cycle(line_items) - line_items.first.order_cycle + def item_order_cycle(line_item) + line_item.order_cycle end - def adjustments_by_type(line_items, type, included: false) + def adjustments_by_type(line_item, type, included: false) total_amount = 0.0 adjustment_type = type == :tax ? 'Spree::TaxRate' : 'EnterpriseFee' - adjustments = line_items.flat_map(&:adjustments) - + adjustments = line_item.adjustments adjustments.each do |adjustment| if adjustment.originator_type == adjustment_type amount = included == adjustment.included ? adjustment.amount : 0.0 @@ -40,9 +39,9 @@ def adjustments_by_type(line_items, type, included: false) total_amount end - def tax_on_fees(line_items, included: false) + def tax_on_fees(line_item, included: false) total_amount = 0.0 - adjustments = line_items.flat_map(&:adjustments) + adjustments = line_item.adjustments adjustments.each do |adjustment| next unless adjustment.originator_type == 'EnterpriseFee' From ed559b52575ee26a30e823bb4ac924ee7f6a4dc2 Mon Sep 17 00:00:00 2001 From: Ahmed Ejaz Date: Thu, 10 Oct 2024 05:54:06 +0500 Subject: [PATCH 12/20] update specs to have more line items --- .../admin/reports/pay_your_suppliers_spec.rb | 131 +++++++++++++----- 1 file changed, 95 insertions(+), 36 deletions(-) diff --git a/spec/system/admin/reports/pay_your_suppliers_spec.rb b/spec/system/admin/reports/pay_your_suppliers_spec.rb index 8bc1760c9bc..a7b7ac99667 100644 --- a/spec/system/admin/reports/pay_your_suppliers_spec.rb +++ b/spec/system/admin/reports/pay_your_suppliers_spec.rb @@ -5,21 +5,34 @@ RSpec.describe "Pay Your Suppliers Report" do include ReportsHelper - let(:hub) { create(:distributor_enterprise) } - let(:order_cycle) { create(:open_order_cycle, distributors: [hub]) } - let(:product) { order.products.first } - let(:variant) { product.variants.first } - let(:supplier) { variant.supplier } - let(:current_user) { hub.owner } - let!(:order) do - create(:completed_order_with_totals, distributor: hub, order_cycle:, line_items_count: 1) + let(:owner) { create(:user) } + let(:hub1) { create(:enterprise, owner:) } + let(:order_cycle1) { create(:open_order_cycle, distributors: [hub1]) } + let!(:order1) do + create( + :completed_order_with_totals, + distributor: hub1, + order_cycle: order_cycle1, + line_items_count: 2 + ) + end + + let(:hub2) { create(:enterprise, owner:) } + let(:product2) { order1.products.first } + let(:variant2) { product2.variants.first } + let(:supplier2) { variant2.supplier } + let(:order_cycle2) { create(:open_order_cycle, distributors: [hub2]) } + let!(:order2) do + create( + :completed_order_with_totals, + distributor: hub2, + order_cycle: order_cycle2, + line_items_count: 3 + ) end - let(:params) { { display_summary_row: true } } - let(:report) { Reporting::Reports::Suppliers::Base.new(current_user, { q: params }) } - let(:report_table_rows) { report.rows } before do - login_as current_user + login_as owner visit admin_reports_path end @@ -53,30 +66,76 @@ "Total ($)" ].join(" ")) - line = page.find('table.report__table tbody tr').text - expect(line).to have_content([ - supplier.name, - supplier.address.full_address, - "none", - "none", - hub.name, - hub.address.full_address, - "none", - order.number, - order.completed_at.to_date.to_s, - order_cycle.name, - order_cycle.orders_open_at.to_date.to_s, - order_cycle.orders_close_at.to_date.to_s, - product.name, - variant.full_name, - '1', - '10.0', - '10.0', - '0.0', - '0.0', - '0.0', - '10.0', - ].compact.join(" ")) + lines = page.all('table.report__table tbody tr').map(&:text) + # 5 line_item rows + 1 summary row = 6 rows + expect(lines.count).to be(6) + + hub1_rows = lines.select { |line| line.include?(hub1.name) } + order1.line_items.each_with_index do |line_item, index| + variant = line_item.variant + supplier = line_item.supplier + product = line_item.variant.product + line = hub1_rows[index] + + expect(line).to have_content([ + supplier.name, + supplier.address.full_address, + "none", + "none", + hub1.name, + hub1.address.full_address, + "none", + order1.number, + order1.completed_at.to_date.to_s, + order_cycle1.name, + order_cycle1.orders_open_at.to_date.to_s, + order_cycle1.orders_close_at.to_date.to_s, + product.name, + variant.full_name, + 1, + 10.0, + 10.0, + 0.0, + 0.0, + 0.0, + 10.0, + ].compact.join(" ")) + end + + hub2_rows = lines.select { |line| line.include?(hub2.name) } + order2.line_items.each_with_index do |line_item, index| + variant = line_item.variant + supplier = line_item.supplier + product = line_item.variant.product + line = hub2_rows[index] + + expect(line).to have_content([ + supplier.name, + supplier.address.full_address, + "none", + "none", + hub2.name, + hub2.address.full_address, + "none", + order2.number, + order2.completed_at.to_date.to_s, + order_cycle2.name, + order_cycle2.orders_open_at.to_date.to_s, + order_cycle2.orders_close_at.to_date.to_s, + product.name, + variant.full_name, + 1, + 10.0, + 10.0, + 0.0, + 0.0, + 0.0, + 10.0, + ].compact.join(" ")) + end + + # summary row + expect(lines.last).to have_content("TOTAL 50.0 50.0 0.0 0.0 0.0 50.0") end end end From 298c0e8d7f9560bd2c19e665d9295717ddaca394 Mon Sep 17 00:00:00 2001 From: Ahmed Ejaz Date: Fri, 1 Nov 2024 20:13:06 +0500 Subject: [PATCH 13/20] fix reported issues: - wrong enterprise fees - always 0 tax on fees --- .../suppliers/helpers/columns_helper.rb | 3 ++- .../helpers/line_items_access_helper.rb | 21 ++++++++++++----- .../pay_your_suppliers_report_spec.rb | 23 ++++++++++++++++--- 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/lib/reporting/reports/suppliers/helpers/columns_helper.rb b/lib/reporting/reports/suppliers/helpers/columns_helper.rb index d91bd40f9a5..8a0d5c19d02 100644 --- a/lib/reporting/reports/suppliers/helpers/columns_helper.rb +++ b/lib/reporting/reports/suppliers/helpers/columns_helper.rb @@ -109,9 +109,10 @@ def total proc do |line_item| total_price = total_excl_vat_and_fees.call(line_item) total_fees = total_fees_excl_vat.call(line_item) + total_fees_tax = total_vat_on_fees.call(line_item) tax = total_tax.call(line_item) - total_price + total_fees + tax + total_price + total_fees + total_fees_tax + tax end end end diff --git a/lib/reporting/reports/suppliers/helpers/line_items_access_helper.rb b/lib/reporting/reports/suppliers/helpers/line_items_access_helper.rb index 26318f17164..937f6cb7a1e 100644 --- a/lib/reporting/reports/suppliers/helpers/line_items_access_helper.rb +++ b/lib/reporting/reports/suppliers/helpers/line_items_access_helper.rb @@ -25,11 +25,22 @@ def item_order_cycle(line_item) line_item.order_cycle end + def suppliers_adjustments(line_item, adjustment_type = 'EnterpriseFee') + adjustments = line_item.adjustments + return adjustments if adjustment_type == 'Spree::TaxRate' + + supplier_name = supplier(line_item).name + adjustments.select do |adjustment| + label = adjustment.label + + label.include?('supplier') && label.include?(supplier_name) + end + end + def adjustments_by_type(line_item, type, included: false) total_amount = 0.0 adjustment_type = type == :tax ? 'Spree::TaxRate' : 'EnterpriseFee' - adjustments = line_item.adjustments - adjustments.each do |adjustment| + suppliers_adjustments(line_item, adjustment_type).each do |adjustment| if adjustment.originator_type == adjustment_type amount = included == adjustment.included ? adjustment.amount : 0.0 total_amount += amount @@ -41,13 +52,11 @@ def adjustments_by_type(line_item, type, included: false) def tax_on_fees(line_item, included: false) total_amount = 0.0 - adjustments = line_item.adjustments - - adjustments.each do |adjustment| + suppliers_adjustments(line_item).each do |adjustment| next unless adjustment.originator_type == 'EnterpriseFee' adjustment.adjustments.each do |fee_adjustment| - next unless adjustment.originator_type == 'Spree::TaxRate' + next unless fee_adjustment.originator_type == 'Spree::TaxRate' amount = included == fee_adjustment.included ? fee_adjustment.amount : 0.0 total_amount += amount diff --git a/spec/lib/reports/suppliers/pay_your_suppliers_report_spec.rb b/spec/lib/reports/suppliers/pay_your_suppliers_report_spec.rb index fc0370ff004..81b80fe44b1 100644 --- a/spec/lib/reports/suppliers/pay_your_suppliers_report_spec.rb +++ b/spec/lib/reports/suppliers/pay_your_suppliers_report_spec.rb @@ -49,12 +49,29 @@ context "with taxes and fees" do let(:line_item) { order.line_items.first } + let!(:enterprise_fee) do + create(:enterprise_fee, enterprise: supplier, inherits_tax_category: true, fee_type: 'sales') + end let!(:fees_adjustment) do - create(:adjustment, originator_type: "EnterpriseFee", adjustable: line_item, amount: 0.1) + create( + :adjustment, + originator: enterprise_fee, + adjustable: line_item, + amount: 0.1, + label: "#{enterprise_fee.name} fee by supplier #{supplier.name}", + ) end let!(:tax_adjustment) do create(:adjustment, originator_type: "Spree::TaxRate", adjustable: line_item, amount: 0.1) end + let!(:tax_on_fee) do + create( + :adjustment, + originator_type: "Spree::TaxRate", + adjustable: fees_adjustment, + amount: 0.01 + ) + end it "Generates the report" do expect(report_table_rows.length).to eq(1) @@ -63,9 +80,9 @@ expect(table_row.total_excl_vat_and_fees.to_f).to eq(10.0) expect(table_row.total_excl_vat.to_f).to eq(10.1) expect(table_row.total_fees_excl_vat.to_f).to eq(0.1) - expect(table_row.total_vat_on_fees.to_f).to eq(0.0) + expect(table_row.total_vat_on_fees.to_f).to eq(0.01) expect(table_row.total_tax.to_f).to eq(0.1) - expect(table_row.total.to_f).to eq(10.2) + expect(table_row.total.to_f).to eq(10.21) end end end From f3e086ad594bc1d4116a22256c14987d086df8d7 Mon Sep 17 00:00:00 2001 From: Ahmed Ejaz Date: Mon, 4 Nov 2024 22:53:56 +0500 Subject: [PATCH 14/20] 12776: remove unnecessary include --- lib/reporting/reports/suppliers/base.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/reporting/reports/suppliers/base.rb b/lib/reporting/reports/suppliers/base.rb index 84938e3b34f..972ab2e6dff 100644 --- a/lib/reporting/reports/suppliers/base.rb +++ b/lib/reporting/reports/suppliers/base.rb @@ -89,7 +89,6 @@ def line_item_includes order: [ :distributor, :adjustments, - { shipments: { shipping_rates: :shipping_method } } ], variant: [:product, :supplier] }] From bc57447d54d3b656ba96e250616796ac8602da45 Mon Sep 17 00:00:00 2001 From: Ahmed Ejaz Date: Tue, 12 Nov 2024 00:55:19 +0500 Subject: [PATCH 15/20] 12776: refactor supplier_adjustments method --- .../helpers/line_items_access_helper.rb | 22 +++++++------------ 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/lib/reporting/reports/suppliers/helpers/line_items_access_helper.rb b/lib/reporting/reports/suppliers/helpers/line_items_access_helper.rb index 937f6cb7a1e..809efb0540e 100644 --- a/lib/reporting/reports/suppliers/helpers/line_items_access_helper.rb +++ b/lib/reporting/reports/suppliers/helpers/line_items_access_helper.rb @@ -27,13 +27,13 @@ def item_order_cycle(line_item) def suppliers_adjustments(line_item, adjustment_type = 'EnterpriseFee') adjustments = line_item.adjustments - return adjustments if adjustment_type == 'Spree::TaxRate' + return adjustments.tax if adjustment_type == 'Spree::TaxRate' - supplier_name = supplier(line_item).name - adjustments.select do |adjustment| + supplier_id = supplier(line_item).id + adjustments.enterprise_fee.select do |adjustment| label = adjustment.label - - label.include?('supplier') && label.include?(supplier_name) + adjustment_enterprise_id = adjustment.originator.enterprise.id + label.include?('supplier') && adjustment_enterprise_id == supplier_id end end @@ -41,10 +41,8 @@ def adjustments_by_type(line_item, type, included: false) total_amount = 0.0 adjustment_type = type == :tax ? 'Spree::TaxRate' : 'EnterpriseFee' suppliers_adjustments(line_item, adjustment_type).each do |adjustment| - if adjustment.originator_type == adjustment_type - amount = included == adjustment.included ? adjustment.amount : 0.0 - total_amount += amount - end + amount = included == adjustment.included ? adjustment.amount : 0.0 + total_amount += amount end total_amount @@ -53,11 +51,7 @@ def adjustments_by_type(line_item, type, included: false) def tax_on_fees(line_item, included: false) total_amount = 0.0 suppliers_adjustments(line_item).each do |adjustment| - next unless adjustment.originator_type == 'EnterpriseFee' - - adjustment.adjustments.each do |fee_adjustment| - next unless fee_adjustment.originator_type == 'Spree::TaxRate' - + adjustment.adjustments.tax.each do |fee_adjustment| amount = included == fee_adjustment.included ? fee_adjustment.amount : 0.0 total_amount += amount end From e2d999da8ddfe765e0d275b1253cd3165129d49e Mon Sep 17 00:00:00 2001 From: Ahmed Ejaz Date: Tue, 12 Nov 2024 03:08:41 +0500 Subject: [PATCH 16/20] 12776: use EnterpriseFeeCalculator in specs --- .../pay_your_suppliers_report_spec.rb | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/spec/lib/reports/suppliers/pay_your_suppliers_report_spec.rb b/spec/lib/reports/suppliers/pay_your_suppliers_report_spec.rb index 81b80fe44b1..ad597d8e024 100644 --- a/spec/lib/reports/suppliers/pay_your_suppliers_report_spec.rb +++ b/spec/lib/reports/suppliers/pay_your_suppliers_report_spec.rb @@ -50,21 +50,32 @@ context "with taxes and fees" do let(:line_item) { order.line_items.first } let!(:enterprise_fee) do - create(:enterprise_fee, enterprise: supplier, inherits_tax_category: true, fee_type: 'sales') - end - let!(:fees_adjustment) do create( - :adjustment, - originator: enterprise_fee, - adjustable: line_item, + :enterprise_fee, + enterprise: supplier, + fee_type: 'sales', amount: 0.1, - label: "#{enterprise_fee.name} fee by supplier #{supplier.name}", ) end let!(:tax_adjustment) do create(:adjustment, originator_type: "Spree::TaxRate", adjustable: line_item, amount: 0.1) end - let!(:tax_on_fee) do + + before do + hub.update!(charges_sales_tax: true) + supplier.update!(charges_sales_tax: true) + + exchange = order_cycle.exchanges.take + exchange.enterprise_fees << enterprise_fee + exchange.exchange_variants.build(variant: line_item.variant) + exchange.incoming = true + exchange.save! + + OpenFoodNetwork::EnterpriseFeeCalculator + .new(hub, order_cycle) + .create_line_item_adjustments_for(line_item) + + fees_adjustment = line_item.adjustments.enterprise_fee.first create( :adjustment, originator_type: "Spree::TaxRate", From 9bcdac8f30ee74796d434aca615c3273e8fcc3dc Mon Sep 17 00:00:00 2001 From: Ahmed Ejaz Date: Wed, 13 Nov 2024 20:00:11 +0500 Subject: [PATCH 17/20] 12776: rename vat to tax --- config/locales/en.yml | 6 +++--- lib/reporting/reports/suppliers/base.rb | 12 ++++++------ .../reports/suppliers/helpers/columns_helper.rb | 14 +++++++------- .../suppliers/pay_your_suppliers_report_spec.rb | 12 ++++++------ 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index 7bff667b078..44834a3d6f5 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -3332,11 +3332,11 @@ See the %{link} to find out more about %{sitename}'s features and to start using report_header_total_units: Total Units report_header_sum_max_total: "Sum Max Total" report_header_total_excl_vat: "Total excl. tax (%{currency_symbol})" - report_header_total_fees_excl_vat: "Total fees excl. tax (%{currency_symbol})" - report_header_total_vat_on_fees: "Total tax on fees (%{currency_symbol})" + report_header_total_fees_excl_tax: "Total fees excl. tax (%{currency_symbol})" + report_header_total_tax_on_fees: "Total tax on fees (%{currency_symbol})" report_header_total: "Total (%{currency_symbol})" report_header_total_incl_vat: "Total incl. tax (%{currency_symbol})" - report_header_total_excl_vat_and_fees: "Total excl. fees and tax (%{currency_symbol})" + report_header_total_excl_fees_and_tax: "Total excl. fees and tax (%{currency_symbol})" report_header_temp_controlled: TempControlled? report_header_is_producer: Producer? report_header_not_confirmed: Not Confirmed diff --git a/lib/reporting/reports/suppliers/base.rb b/lib/reporting/reports/suppliers/base.rb index 972ab2e6dff..f6723ffdc89 100644 --- a/lib/reporting/reports/suppliers/base.rb +++ b/lib/reporting/reports/suppliers/base.rb @@ -40,10 +40,10 @@ def columns product:, variant_unit_name:, quantity:, - total_excl_vat_and_fees:, + total_excl_fees_and_tax:, total_excl_vat:, - total_fees_excl_vat:, - total_vat_on_fees:, + total_fees_excl_tax:, + total_tax_on_fees:, total_tax:, total:, } @@ -58,10 +58,10 @@ def rules summary_hash = Hash.new(0) line_items.each do |line_item| - summary_hash[:total_excl_vat_and_fees] += total_excl_vat_and_fees.call(line_item) + summary_hash[:total_excl_fees_and_tax] += total_excl_fees_and_tax.call(line_item) summary_hash[:total_excl_vat] += total_excl_vat.call(line_item) - summary_hash[:total_fees_excl_vat] += total_fees_excl_vat.call(line_item) - summary_hash[:total_vat_on_fees] += total_vat_on_fees.call(line_item) + summary_hash[:total_fees_excl_tax] += total_fees_excl_tax.call(line_item) + summary_hash[:total_tax_on_fees] += total_tax_on_fees.call(line_item) summary_hash[:total_tax] += total_tax.call(line_item) summary_hash[:total] += total.call(line_item) end diff --git a/lib/reporting/reports/suppliers/helpers/columns_helper.rb b/lib/reporting/reports/suppliers/helpers/columns_helper.rb index 8a0d5c19d02..abac2f67b18 100644 --- a/lib/reporting/reports/suppliers/helpers/columns_helper.rb +++ b/lib/reporting/reports/suppliers/helpers/columns_helper.rb @@ -71,7 +71,7 @@ def quantity proc { |line_item| line_item.quantity } end - def total_excl_vat_and_fees + def total_excl_fees_and_tax proc do |line_item| included_tax = adjustments_by_type(line_item, :tax, included: true) line_item.amount - included_tax @@ -81,18 +81,18 @@ def total_excl_vat_and_fees def total_excl_vat proc do |line_item| total_fees = adjustments_by_type(line_item, :fees) - total_excl_vat_and_fees.call(line_item) + total_fees + total_excl_fees_and_tax.call(line_item) + total_fees end end - def total_fees_excl_vat + def total_fees_excl_tax proc do |line_item| included_tax = tax_on_fees(line_item, included: true) adjustments_by_type(line_item, :fees) - included_tax end end - def total_vat_on_fees + def total_tax_on_fees proc { |line_item| tax_on_fees(line_item) } end @@ -107,9 +107,9 @@ def total_tax def total proc do |line_item| - total_price = total_excl_vat_and_fees.call(line_item) - total_fees = total_fees_excl_vat.call(line_item) - total_fees_tax = total_vat_on_fees.call(line_item) + total_price = total_excl_fees_and_tax.call(line_item) + total_fees = total_fees_excl_tax.call(line_item) + total_fees_tax = total_tax_on_fees.call(line_item) tax = total_tax.call(line_item) total_price + total_fees + total_fees_tax + tax diff --git a/spec/lib/reports/suppliers/pay_your_suppliers_report_spec.rb b/spec/lib/reports/suppliers/pay_your_suppliers_report_spec.rb index ad597d8e024..29fab7ea7e2 100644 --- a/spec/lib/reports/suppliers/pay_your_suppliers_report_spec.rb +++ b/spec/lib/reports/suppliers/pay_your_suppliers_report_spec.rb @@ -38,10 +38,10 @@ expect(table_row.product).to eq(product.name) expect(table_row.variant_unit_name).to eq(variant.full_name) expect(table_row.quantity).to eq(1) - expect(table_row.total_excl_vat_and_fees.to_f).to eq(10.0) + expect(table_row.total_excl_fees_and_tax.to_f).to eq(10.0) expect(table_row.total_excl_vat.to_f).to eq(10.0) - expect(table_row.total_fees_excl_vat.to_f).to eq(0.0) - expect(table_row.total_vat_on_fees.to_f).to eq(0.0) + expect(table_row.total_fees_excl_tax.to_f).to eq(0.0) + expect(table_row.total_tax_on_fees.to_f).to eq(0.0) expect(table_row.total_tax.to_f).to eq(0.0) expect(table_row.total.to_f).to eq(10.0) end @@ -88,10 +88,10 @@ expect(report_table_rows.length).to eq(1) table_row = report_table_rows.first - expect(table_row.total_excl_vat_and_fees.to_f).to eq(10.0) + expect(table_row.total_excl_fees_and_tax.to_f).to eq(10.0) expect(table_row.total_excl_vat.to_f).to eq(10.1) - expect(table_row.total_fees_excl_vat.to_f).to eq(0.1) - expect(table_row.total_vat_on_fees.to_f).to eq(0.01) + expect(table_row.total_fees_excl_tax.to_f).to eq(0.1) + expect(table_row.total_tax_on_fees.to_f).to eq(0.01) expect(table_row.total_tax.to_f).to eq(0.1) expect(table_row.total.to_f).to eq(10.21) end From 6b3b29ac39c90770dfa156757a5447b83a18fd1f Mon Sep 17 00:00:00 2001 From: Ahmed Ejaz Date: Thu, 14 Nov 2024 02:16:07 +0500 Subject: [PATCH 18/20] 12776: refactor spec --- .../pay_your_suppliers_report_spec.rb | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/spec/lib/reports/suppliers/pay_your_suppliers_report_spec.rb b/spec/lib/reports/suppliers/pay_your_suppliers_report_spec.rb index 29fab7ea7e2..9494342ee06 100644 --- a/spec/lib/reports/suppliers/pay_your_suppliers_report_spec.rb +++ b/spec/lib/reports/suppliers/pay_your_suppliers_report_spec.rb @@ -49,21 +49,33 @@ context "with taxes and fees" do let(:line_item) { order.line_items.first } + let(:tax_category) { + create( + :tax_category, + tax_rates: [ + create( + :tax_rate, + zone: create(:zone_with_member) + ) + ] + ) + } let!(:enterprise_fee) do create( :enterprise_fee, enterprise: supplier, fee_type: 'sales', amount: 0.1, + tax_category: ) end - let!(:tax_adjustment) do - create(:adjustment, originator_type: "Spree::TaxRate", adjustable: line_item, amount: 0.1) - end before do + # Prepare order or line_item to have respective tax adjustments hub.update!(charges_sales_tax: true) supplier.update!(charges_sales_tax: true) + line_item.variant.update!(tax_category:) + line_item.copy_tax_category exchange = order_cycle.exchanges.take exchange.enterprise_fees << enterprise_fee @@ -75,13 +87,7 @@ .new(hub, order_cycle) .create_line_item_adjustments_for(line_item) - fees_adjustment = line_item.adjustments.enterprise_fee.first - create( - :adjustment, - originator_type: "Spree::TaxRate", - adjustable: fees_adjustment, - amount: 0.01 - ) + order.create_tax_charge! end it "Generates the report" do @@ -92,8 +98,8 @@ expect(table_row.total_excl_vat.to_f).to eq(10.1) expect(table_row.total_fees_excl_tax.to_f).to eq(0.1) expect(table_row.total_tax_on_fees.to_f).to eq(0.01) - expect(table_row.total_tax.to_f).to eq(0.1) - expect(table_row.total.to_f).to eq(10.21) + expect(table_row.total_tax.to_f).to eq(1.0) + expect(table_row.total.to_f).to eq(11.11) end end end From 4965e2bb9ae6be46c95c2481b2d89cb69927969b Mon Sep 17 00:00:00 2001 From: Ahmed Ejaz Date: Thu, 14 Nov 2024 02:17:27 +0500 Subject: [PATCH 19/20] Update lib/reporting/reports/suppliers/helpers/line_items_access_helper.rb Co-authored-by: David Cook --- .../reports/suppliers/helpers/line_items_access_helper.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/reporting/reports/suppliers/helpers/line_items_access_helper.rb b/lib/reporting/reports/suppliers/helpers/line_items_access_helper.rb index 809efb0540e..3152cac7dd0 100644 --- a/lib/reporting/reports/suppliers/helpers/line_items_access_helper.rb +++ b/lib/reporting/reports/suppliers/helpers/line_items_access_helper.rb @@ -29,10 +29,10 @@ def suppliers_adjustments(line_item, adjustment_type = 'EnterpriseFee') adjustments = line_item.adjustments return adjustments.tax if adjustment_type == 'Spree::TaxRate' - supplier_id = supplier(line_item).id + supplier_id = line_item.supplier_id adjustments.enterprise_fee.select do |adjustment| label = adjustment.label - adjustment_enterprise_id = adjustment.originator.enterprise.id + adjustment_enterprise_id = adjustment.originator.enterprise_id label.include?('supplier') && adjustment_enterprise_id == supplier_id end end From ed7685222ec1a81841ce363dd7d42ee65f173ff5 Mon Sep 17 00:00:00 2001 From: Ahmed Ejaz Date: Fri, 15 Nov 2024 02:23:15 +0500 Subject: [PATCH 20/20] 12776: fix included tax on fees --- lib/reporting/reports/suppliers/helpers/columns_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/reporting/reports/suppliers/helpers/columns_helper.rb b/lib/reporting/reports/suppliers/helpers/columns_helper.rb index abac2f67b18..2405a5442aa 100644 --- a/lib/reporting/reports/suppliers/helpers/columns_helper.rb +++ b/lib/reporting/reports/suppliers/helpers/columns_helper.rb @@ -93,7 +93,7 @@ def total_fees_excl_tax end def total_tax_on_fees - proc { |line_item| tax_on_fees(line_item) } + proc { |line_item| tax_on_fees(line_item) + tax_on_fees(line_item, included: true) } end def total_tax