From e9367b1f86f8463cf6a58a357aa9fe0d59b3b7f5 Mon Sep 17 00:00:00 2001 From: Mohamed ABDELLANI Date: Thu, 26 Jan 2023 09:00:00 +0100 Subject: [PATCH] add enterprise fees with tax report by order --- app/models/spree/order.rb | 7 +- config/locales/en.yml | 3 + ...nterprise_fees_with_tax_report_by_order.rb | 259 ++++++++++++++++++ lib/reporting/reports/list.rb | 4 + 4 files changed, 271 insertions(+), 2 deletions(-) create mode 100644 lib/reporting/reports/enterprise_fee_summary/enterprise_fees_with_tax_report_by_order.rb diff --git a/app/models/spree/order.rb b/app/models/spree/order.rb index d180a4b833..a1fed156dd 100644 --- a/app/models/spree/order.rb +++ b/app/models/spree/order.rb @@ -544,8 +544,11 @@ module Spree shipment_adjustments.reload.tax.sum(:amount) end - def enterprise_fee_tax - all_adjustments.tax.where(adjustable: all_adjustments.enterprise_fee).sum(:amount) + def enterprise_fee_tax(included: false,added: false) + query = all_adjustments.tax + query = query.inclusive if included == true + query = query.additional if added == true + query.where(adjustable: all_adjustments.enterprise_fee).sum(:amount) end def total_tax diff --git a/config/locales/en.yml b/config/locales/en.yml index 8349a9018e..dd6ec616fe 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1514,6 +1514,7 @@ en: enterprise_fee_summary: name: "Enterprise Fee Summary" description: "Summary of Enterprise Fees collected" + enterprise_fees_with_tax_report_by_order: "Enterprise Fees With Tax Report By Order" errors: no_report_type: "Please specify a report type" report_not_found: "Report not found" @@ -2942,6 +2943,8 @@ See the %{link} to find out more about %{sitename}'s features and to start using report_header_enterprise_fee_type: Type report_header_enterprise_fee_owner: Owner report_header_customer: Customer + report_header_customer_first_name: First Name + report_header_customer_last_name: Last Name report_header_customer_code: Customer Code report_header_product: Product report_header_product_properties: Product Properties diff --git a/lib/reporting/reports/enterprise_fee_summary/enterprise_fees_with_tax_report_by_order.rb b/lib/reporting/reports/enterprise_fee_summary/enterprise_fees_with_tax_report_by_order.rb new file mode 100644 index 0000000000..9aab131dfc --- /dev/null +++ b/lib/reporting/reports/enterprise_fee_summary/enterprise_fees_with_tax_report_by_order.rb @@ -0,0 +1,259 @@ +# frozen_string_literal: true + +module Reporting + module Reports + module EnterpriseFeeSummary + class EnterpriseFeesWithTaxReportByOrder < ReportTemplate + attr_accessor :permissions, :parameters + + def initialize(user, params = {}, render: false) + super(user, params, render: render) + @parameters = Parameters.new(p || {}) + @parameters.validate! + @permissions = Permissions.new(user) + @parameters.authorize!(@permissions) + end + + def search + report_line_items.orders + end + + 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 query_result + # The objective is to group the orders by + # [enterpirse fees,tax_rate, order] + orders = search.result.to_a + orders.flat_map(&join_enterprise_fee) + .flat_map(&join_tax_rate) + .group_by(&group_keys) + .map(&change_root_to_order) + end + + def join_enterprise_fee + proc do |order| + order + .all_adjustments + .enterprise_fee + .group('originator_id') + .pluck("originator_id", 'array_agg(id)') + .map do |enterprise_fee_id, enterprise_fee_adjustment_ids| + { + enterprise_fee_id: enterprise_fee_id, + enterprise_fee_adjustment_ids: enterprise_fee_adjustment_ids, + order: order + } + end + end + end + + def join_tax_rate + proc do |item| + tax_rate_ids = item[:order].all_adjustments.tax.where( + adjustable_id: item[:enterprise_fee_adjustment_ids], + adjustable_type: "Spree::Adjustment" + ).pluck(: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, + enterprise_fee_id: item[:enterprise_fee_id], + order: item[:order], + } + end + end + end + + def group_keys + proc do |hash| + [ + hash[:tax_rate_id], + hash[:enterprise_fee_id], + hash[:order].id + ] + end + end + + def change_root_to_order + proc do |k, v| + [k, v.first[:order]] + end + end + + def columns + { + distributor: :distributor, + order_cycle: :order_cycle, + order_number: :order_number, + enterprise_fee_name: :enterprise_fee_name, + enterprise_fee_type: :enterprise_fee_type, + enterprise_fee_owner: :enterprise_fee_owner, + tax_category: :tax_category, + tax_rate_name: :tax_rate_name, + tax_rate: :tax_rate_amount, + total_excl_tax: :total_excl_tax, + tax: :tax, + total_incl_tax: :total_incl_tax, + customer_first_name: :customer_first_name, + customer_last_name: :customer_last_name, + customer_code: :customer_code, + customer_email: :customer_email + } + end + + def rules + [ + { group_by: :distributor }, + { group_by: :order_cycle }, + { + group_by: :order_number, + summary_row: proc do |_key, items, _rows| + item = items.first + order = item.second + enterprise_fees = order.all_adjustments.enterprise_fee.sum(:amount) + { + total_excl_tax: enterprise_fees - order.enterprise_fee_tax(included: true), + tax: order.enterprise_fee_tax, + total_incl_tax: enterprise_fees + order.enterprise_fee_tax(added: true), + customer_first_name: order.customer&.first_name, + customer_last_name: order.customer&.last_name, + customer_code: order.customer&.code, + customer_email: order.customer&.email + } + 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 enterprise_fee_name(query_result_row) + enterprise_fee(query_result_row).name + end + + def enterprise_fee_type(query_result_row) + enterprise_fee(query_result_row).fee_type + end + + def enterprise_fee_owner(query_result_row) + enterprise_fee(query_result_row).enterprise.name + 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_id = order(query_result_row).id + enterpise_fee_id = enterprise_fee_id(query_result_row) + amount = Spree::Adjustment.enterprise_fee + .where(order_id: order_id) + .where(originator_id: enterpise_fee_id) + .pick("sum(amount)") || 0 + amount - tax(query_result_row, all: true, included: true) + end + + def tax(query_result_row, all: false, included: nil) + order_id = order(query_result_row).id + adjustment_ids = enterprise_fee_adjustemnt_ids(query_result_row) + query = Spree::Adjustment.tax + query = query.where(included: true) unless included.nil? + query = query.where(originator_id: tax_rate_id(query_result_row)) unless all == true + query.where(order_id: order_id) + .where(adjustable_type: 'Spree::Adjustment') + .where(adjustable_id: adjustment_ids) + .pick("sum(amount)") || 0 + end + + def total_incl_tax(query_result_row) + total_excl_tax(query_result_row) + tax(query_result_row, all: false) + end + + def customer_first_name(query_result_row) + order(query_result_row).customer&.first_name + end + + def customer_last_name(query_result_row) + order(query_result_row).customer&.last_name + end + + def customer_code(query_result_row) + order(query_result_row).customer&.code + end + + def customer_email(query_result_row) + order(query_result_row).customer&.email + end + + def enterprise_fee_adjustemnt_ids(query_result_row) + order_id = order(query_result_row).id + enterpise_fee_id = enterprise_fee_id(query_result_row) + Spree::Adjustment.enterprise_fee + .where(order_id: order_id) + .where(originator_id: enterpise_fee_id) + .pluck(:id) + end + + def enterprise_fee(query_result_row) + order(query_result_row).all_adjustments + .enterprise_fee + .find_by(originator_id: enterprise_fee_id(query_result_row)) + .originator + end + + def tax_rate(query_result_row) + return nil if tax_rate_id(query_result_row).nil? + + Spree::TaxRate.find(tax_rate_id(query_result_row)) + end + + def order(query_result_row) + query_result_row.second + end + + def tax_rate_id(query_result_row) + keys(query_result_row)[0] + end + + def supplier_id(query_result_row) + keys(query_result_row)[2] + end + + def enterprise_fee_id(query_result_row) + keys(query_result_row)[1] + end + + def keys(query_result_row) + query_result_row.first + end + end + end + end +end diff --git a/lib/reporting/reports/list.rb b/lib/reporting/reports/list.rb index e1adc90f1c..910565fcda 100644 --- a/lib/reporting/reports/list.rb +++ b/lib/reporting/reports/list.rb @@ -63,6 +63,10 @@ module Reporting 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 + ] ] end