Add filtering to enterprise fee summary

This commit is contained in:
Kristina Lim
2018-10-14 17:35:28 +08:00
committed by luisramos0
parent 2407531957
commit 24ab2e7fb0
3 changed files with 329 additions and 17 deletions

View File

@@ -17,7 +17,7 @@ module OrderManagement
end
def enterprise_fees_by_customer
Scope.new.all
Scope.new.apply_filters(parameters).result
end
def enterprise_fee_type_totals

View File

@@ -2,11 +2,22 @@ module OrderManagement
module Reports
module EnterpriseFeeSummary
class Scope
attr_accessor :parameters
def initialize
setup_default_scope
end
def all
def apply_filters(params)
filter_by_date(params)
filter_by_distribution(params)
filter_by_fee(params)
self
end
def result
group_data.select_attributes
@scope.all
end
@@ -275,6 +286,30 @@ module OrderManagement
)
end
def filter_by_date(params)
filter_scope("spree_orders.completed_at >= ?", params.start_at) \
if params.start_at.present?
filter_scope("spree_orders.completed_at <= ?", params.end_at) if params.end_at.present?
end
def filter_by_distribution(params)
filter_scope(spree_orders: { distributor_id: params.distributor_ids }) \
if params.distributor_ids.present?
filter_scope(spree_products: { supplier_id: params.producer_ids }) \
if params.producer_ids.present?
filter_scope(spree_orders: { order_cycle_id: params.order_cycle_ids }) \
if params.order_cycle_ids.present?
end
def filter_by_fee(params)
filter_scope(enterprise_fees: { id: params.enterprise_fee_ids }) \
if params.enterprise_fee_ids.present?
filter_scope(spree_shipping_methods: { id: params.shipping_method_ids }) \
if params.shipping_method_ids.present?
filter_scope(spree_payment_methods: { id: params.payment_method_ids }) \
if params.payment_method_ids.present?
end
def group_data
chain_to_scope do
group("enterprise_fees.id", "enterprises.id", "customers.id", "hubs.id",
@@ -314,6 +349,12 @@ module OrderManagement
joins(join_string)
end
end
def filter_scope(*args)
chain_to_scope do
where(*args)
end
end
end
end
end

View File

@@ -4,6 +4,8 @@ require "order_management/reports/enterprise_fee_summary/report_service"
require "order_management/reports/enterprise_fee_summary/parameters"
describe OrderManagement::Reports::EnterpriseFeeSummary::ReportService do
let(:report_klass) { OrderManagement::Reports::EnterpriseFeeSummary }
let!(:shipping_method) do
create(:shipping_method, name: "Sample Shipping Method", calculator: per_item_calculator(1.0))
end
@@ -75,9 +77,9 @@ describe OrderManagement::Reports::EnterpriseFeeSummary::ReportService do
let!(:another_customer) { create(:customer, name: "Another Customer") }
describe "grouping and sorting of entries" do
let!(:customer_order) { prepare_completed_order(customer: customer) }
let!(:second_customer_order) { prepare_completed_order(customer: customer) }
let!(:other_customer_order) { prepare_completed_order(customer: another_customer) }
let!(:customer_order) { prepare_order(customer: customer) }
let!(:second_customer_order) { prepare_order(customer: customer) }
let!(:other_customer_order) { prepare_order(customer: another_customer) }
let(:parameters) { OrderManagement::Reports::EnterpriseFeeSummary::Parameters.new }
let(:service) { described_class.new(parameters, nil) }
@@ -138,6 +140,241 @@ describe OrderManagement::Reports::EnterpriseFeeSummary::ReportService do
end
end
describe "filters entries correctly" do
let(:parameters) { report_klass::Parameters.new(parameters_attributes) }
let(:service) { described_class.new(parameters, nil) }
context "filtering by completion date" do
let(:timestamp) { Time.zone.local(2018, 1, 5, 14, 30, 5) }
let!(:customer_a) { create(:customer, name: "Customer A") }
let!(:customer_b) { create(:customer, name: "Customer B") }
let!(:customer_c) { create(:customer, name: "Customer C") }
let!(:order_placed_before_timestamp) do
prepare_order(customer: customer_a).tap do |order|
order.update_column(:completed_at, timestamp - 1.second)
end
end
let!(:order_placed_during_timestamp) do
prepare_order(customer: customer_b).tap do |order|
order.update_column(:completed_at, timestamp)
end
end
let!(:order_placed_after_timestamp) do
prepare_order(customer: customer_c).tap do |order|
order.update_column(:completed_at, timestamp + 1.second)
end
end
context "on or after start_at" do
let(:parameters_attributes) { { start_at: timestamp } }
it "filters entries" do
totals = service.enterprise_fee_type_totals.list
expect_total_matches(totals, 0, fee_type: "Shipment", customer_name: "Customer A")
expect_total_matches(totals, 1, fee_type: "Shipment", customer_name: "Customer B")
expect_total_matches(totals, 1, fee_type: "Shipment", customer_name: "Customer C")
end
end
context "on or before end_at" do
let(:parameters_attributes) { { end_at: timestamp } }
it "filters entries" do
totals = service.enterprise_fee_type_totals.list
expect_total_matches(totals, 1, fee_type: "Shipment", customer_name: "Customer A")
expect_total_matches(totals, 1, fee_type: "Shipment", customer_name: "Customer B")
expect_total_matches(totals, 0, fee_type: "Shipment", customer_name: "Customer C")
end
end
end
describe "for specified shops" do
let!(:distributor_a) do
create(:distributor_enterprise, name: "Distributor A", payment_methods: [payment_method],
shipping_methods: [shipping_method])
end
let!(:distributor_b) do
create(:distributor_enterprise, name: "Distributor B", payment_methods: [payment_method],
shipping_methods: [shipping_method])
end
let!(:distributor_c) do
create(:distributor_enterprise, name: "Distributor C", payment_methods: [payment_method],
shipping_methods: [shipping_method])
end
let!(:order_a) { prepare_order(distributor: distributor_a) }
let!(:order_b) { prepare_order(distributor: distributor_b) }
let!(:order_c) { prepare_order(distributor: distributor_c) }
let(:parameters_attributes) { { distributor_ids: [distributor_a.id, distributor_b.id] } }
it "filters entries" do
totals = service.enterprise_fee_type_totals.list
expect_total_matches(totals, 1, fee_type: "Shipment", enterprise_name: "Distributor A")
expect_total_matches(totals, 1, fee_type: "Shipment", enterprise_name: "Distributor B")
expect_total_matches(totals, 0, fee_type: "Shipment", enterprise_name: "Distributor C")
end
end
describe "for specified suppliers" do
let!(:producer_a) { create(:supplier_enterprise, name: "Producer A") }
let!(:producer_b) { create(:supplier_enterprise, name: "Producer B") }
let!(:producer_c) { create(:supplier_enterprise, name: "Producer C") }
let!(:fee_a) { create(:enterprise_fee, name: "Fee A", enterprise: producer_a) }
let!(:fee_b) { create(:enterprise_fee, name: "Fee B", enterprise: producer_b) }
let!(:fee_c) { create(:enterprise_fee, name: "Fee C", enterprise: producer_c) }
let!(:product_a) { create(:product, supplier: producer_a) }
let!(:product_b) { create(:product, supplier: producer_b) }
let!(:product_c) { create(:product, supplier: producer_c) }
let!(:variant_a) do
prepare_variant(product: product_a, producer: producer_a, incoming_exchange_fees: [fee_a])
end
let!(:variant_b) do
prepare_variant(product: product_b, producer: producer_b, incoming_exchange_fees: [fee_b])
end
let!(:variant_c) do
prepare_variant(product: product_c, producer: producer_c, incoming_exchange_fees: [fee_c])
end
let!(:order_a) { prepare_order(variant: variant_a) }
let!(:order_b) { prepare_order(variant: variant_b) }
let!(:order_c) { prepare_order(variant: variant_c) }
let(:parameters_attributes) { { producer_ids: [producer_a.id, producer_b.id] } }
it "filters entries" do
totals = service.enterprise_fee_type_totals.list
expect_total_matches(totals, 1, fee_name: "Fee A", enterprise_name: "Producer A")
expect_total_matches(totals, 1, fee_name: "Fee B", enterprise_name: "Producer B")
expect_total_matches(totals, 0, fee_name: "Fee C", enterprise_name: "Producer C")
end
end
describe "for specified order cycles" do
let!(:distributor_a) do
create(:distributor_enterprise, name: "Distributor A", payment_methods: [payment_method],
shipping_methods: [shipping_method])
end
let!(:distributor_b) do
create(:distributor_enterprise, name: "Distributor B", payment_methods: [payment_method],
shipping_methods: [shipping_method])
end
let!(:distributor_c) do
create(:distributor_enterprise, name: "Distributor C", payment_methods: [payment_method],
shipping_methods: [shipping_method])
end
let!(:order_cycle_a) { create(:simple_order_cycle, coordinator: coordinator) }
let!(:order_cycle_b) { create(:simple_order_cycle, coordinator: coordinator) }
let!(:order_cycle_c) { create(:simple_order_cycle, coordinator: coordinator) }
let!(:variant_a) { prepare_variant(distributor: distributor_a, order_cycle: order_cycle_a) }
let!(:variant_b) { prepare_variant(distributor: distributor_b, order_cycle: order_cycle_b) }
let!(:variant_c) { prepare_variant(distributor: distributor_c, order_cycle: order_cycle_c) }
let!(:order_a) { prepare_order(order_cycle: order_cycle_a, distributor: distributor_a) }
let!(:order_b) { prepare_order(order_cycle: order_cycle_b, distributor: distributor_b) }
let!(:order_c) { prepare_order(order_cycle: order_cycle_c, distributor: distributor_c) }
let(:parameters_attributes) { { order_cycle_ids: [order_cycle_a.id, order_cycle_b.id] } }
it "filters entries" do
totals = service.enterprise_fee_type_totals.list
expect_total_matches(totals, 1, fee_type: "Shipment", enterprise_name: "Distributor A")
expect_total_matches(totals, 1, fee_type: "Shipment", enterprise_name: "Distributor B")
expect_total_matches(totals, 0, fee_type: "Shipment", enterprise_name: "Distributor C")
end
end
describe "for specified enterprise fees" do
let!(:fee_a) { create(:enterprise_fee, name: "Fee A", enterprise: distributor) }
let!(:fee_b) { create(:enterprise_fee, name: "Fee B", enterprise: distributor) }
let!(:fee_c) { create(:enterprise_fee, name: "Fee C", enterprise: distributor) }
let!(:variant) { prepare_variant(outgoing_exchange_fees: [fee_a, fee_b, fee_c]) }
let!(:order) { prepare_order(variant: variant) }
let(:parameters_attributes) { { enterprise_fee_ids: [fee_a.id, fee_b.id] } }
it "filters entries" do
totals = service.enterprise_fee_type_totals.list
expect_total_matches(totals, 1, fee_name: "Fee A")
expect_total_matches(totals, 1, fee_name: "Fee B")
expect_total_matches(totals, 0, fee_name: "Fee C")
end
end
describe "for specified shipping methods" do
let!(:shipping_method_a) do
create(:shipping_method, name: "Shipping A", distributors: [distributor])
end
let!(:shipping_method_b) do
create(:shipping_method, name: "Shipping B", distributors: [distributor])
end
let!(:shipping_method_c) do
create(:shipping_method, name: "Shipping C", distributors: [distributor])
end
let!(:order_a) { prepare_order(shipping_method: shipping_method_a) }
let!(:order_b) { prepare_order(shipping_method: shipping_method_b) }
let!(:order_c) { prepare_order(shipping_method: shipping_method_c) }
let(:parameters_attributes) do
{ shipping_method_ids: [shipping_method_a.id, shipping_method_b.id] }
end
it "filters entries" do
totals = service.enterprise_fee_type_totals.list
expect_total_matches(totals, 1, fee_name: "Shipping A")
expect_total_matches(totals, 1, fee_name: "Shipping B")
expect_total_matches(totals, 0, fee_name: "Shipping C")
end
end
describe "for specified payment methods" do
let!(:payment_method_a) do
create(:payment_method, name: "Payment A", distributors: [distributor])
end
let!(:payment_method_b) do
create(:payment_method, name: "Payment B", distributors: [distributor])
end
let!(:payment_method_c) do
create(:payment_method, name: "Payment C", distributors: [distributor])
end
let!(:order_a) { prepare_order(payment_method: payment_method_a) }
let!(:order_b) { prepare_order(payment_method: payment_method_b) }
let!(:order_c) { prepare_order(payment_method: payment_method_c) }
let(:parameters_attributes) do
{ payment_method_ids: [payment_method_a.id, payment_method_b.id] }
end
it "filters entries" do
totals = service.enterprise_fee_type_totals.list
expect_total_matches(totals, 1, fee_name: "Payment A")
expect_total_matches(totals, 1, fee_name: "Payment B")
expect_total_matches(totals, 0, fee_name: "Payment C")
end
end
end
# Helper methods for example group
def expect_total_attributes(total, expected_attribute_list)
@@ -148,6 +385,10 @@ describe OrderManagement::Reports::EnterpriseFeeSummary::ReportService do
expect(actual_attribute_list).to eq(expected_attribute_list)
end
def expect_total_matches(totals, count, attributes)
expect(count_totals(totals, attributes)).to eq(count)
end
def prepare_tax_category(name)
create(:tax_category, name: name)
end
@@ -157,7 +398,7 @@ describe OrderManagement::Reports::EnterpriseFeeSummary::ReportService do
shipping_method: shipping_method, variant: variant }
end
def prepare_order(options = {})
def setup_order(options = {})
target = default_order_options.merge(options)
create(:order, customer: target[:customer], distributor: target[:distributor],
@@ -168,8 +409,8 @@ describe OrderManagement::Reports::EnterpriseFeeSummary::ReportService do
end
end
def prepare_completed_order(options = {})
order = prepare_order(options)
def prepare_order(options = {})
order = setup_order(options)
complete_order(order, options)
order.reload
end
@@ -182,16 +423,38 @@ describe OrderManagement::Reports::EnterpriseFeeSummary::ReportService do
while !order.completed? do break unless order.next! end
end
def prepare_variant(options = {})
variant = create(:variant, product: product, is_master: false)
exchange = create(:exchange, incoming: true, order_cycle: order_cycle, sender: producer,
receiver: coordinator, variants: [variant])
attach_enterprise_fees(exchange, options[:incoming_exchange_fees] || [])
def default_variant_options
{ product: product, producer: producer, coordinator: coordinator, distributor: distributor,
order_cycle: order_cycle }
end
exchange = create(:exchange, incoming: false, order_cycle: order_cycle, sender: coordinator,
receiver: distributor, variants: [variant])
attach_enterprise_fees(exchange, options[:outgoing_exchange_fees] || [])
variant
def prepare_variant(options = {})
target = default_variant_options.merge(options)
create(:variant, product: target[:product], is_master: false).tap do |variant|
exchange_options = { producer: target[:producer], coordinator: target[:coordinator],
distributor: target[:distributor],
incoming_exchange_fees: target[:incoming_exchange_fees],
outgoing_exchange_fees: target[:outgoing_exchange_fees] }
setup_exchanges(target[:order_cycle], variant, exchange_options)
end
end
def setup_exchanges(order_cycle, variant, options)
setup_exchange(order_cycle, variant, true, sender: options[:producer],
receiver: options[:coordinator],
enterprise_fees: options[:incoming_exchange_fees])
setup_exchange(order_cycle, variant, false, sender: options[:coordinator],
receiver: options[:distributor],
enterprise_fees: options[:outgoing_exchange_fees])
end
def setup_exchange(order_cycle, variant, incoming, options)
exchange_attributes = { order_cycle_id: order_cycle.id, incoming: incoming,
sender_id: options[:sender].id, receiver_id: options[:receiver].id }
exchange = Exchange.where(exchange_attributes).first || create(:exchange, exchange_attributes)
exchange.variants << variant
attach_enterprise_fees(exchange, options[:enterprise_fees] || [])
end
def attach_enterprise_fees(exchange, enterprise_fees)
@@ -203,4 +466,12 @@ describe OrderManagement::Reports::EnterpriseFeeSummary::ReportService do
def per_item_calculator(amount)
Spree::Calculator::PerItem.new(preferred_amount: amount)
end
def count_totals(totals, attributes)
totals.count do |data|
attributes.all? do |attribute_name, attribute_value|
data.public_send(attribute_name) == attribute_value
end
end
end
end