Merge pull request #12594 from dacook/12559-fix-orders-and-distributors-report

Hide customer data on orders_and_distributors report
This commit is contained in:
Rachel Arnould
2024-07-03 13:12:42 +02:00
committed by GitHub
2 changed files with 151 additions and 109 deletions

View File

@@ -32,27 +32,27 @@ module Reporting
# rubocop:enable Metrics/AbcSize
def search
permissions.visible_orders.select("DISTINCT spree_orders.*").
complete.not_state(:canceled).
ransack(ransack_params)
report_line_items.orders
end
def query_result
orders = search.result
# Mask non editable order details
editable_orders_ids = permissions.editable_orders.select(&:id).map(&:id)
orders
.filter { |order| order.in?(editable_orders_ids) }
.each { |order| Orders::MaskDataService.new(order).call }
# Get Line Items
orders.map(&:line_items).flatten
report_line_items.list(line_item_includes)
end
private
def line_item_includes
[{ variant: { product: :supplier },
order: [:bill_address, :payments, { distributor: :address }] }]
end
def permissions
@permissions ||= ::Permissions::Order.new(user, ransack_params)
end
def report_line_items
@report_line_items ||= Reporting::LineItems.new(permissions, params)
end
end
end
end

View File

@@ -2,110 +2,152 @@
require 'spec_helper'
module Reporting
module Reports
module OrdersAndDistributors
RSpec.describe Base do
describe 'orders and distributors report' do
it 'should return a header row describing the report' do
subject = Base.new nil
RSpec.describe Reporting::Reports::OrdersAndDistributors::Base do
describe 'orders and distributors report' do
subject { described_class.new nil }
expect(subject.table_headers).to eq(
[
'Order date', 'Order Id',
'Customer Name', 'Customer Email', 'Customer Phone', 'Customer City',
'SKU', 'Item name', 'Variant', 'Quantity', 'Max Quantity', 'Cost', 'Shipping Cost',
'Payment Method',
'Distributor', 'Distributor address', 'Distributor city', 'Distributor postcode',
'Shipping Method', 'Shipping instructions'
]
)
it 'should return a header row describing the report' do
expect(subject.table_headers).to eq(
[
'Order date', 'Order Id',
'Customer Name', 'Customer Email', 'Customer Phone', 'Customer City',
'SKU', 'Item name', 'Variant', 'Quantity', 'Max Quantity', 'Cost', 'Shipping Cost',
'Payment Method',
'Distributor', 'Distributor address', 'Distributor city', 'Distributor postcode',
'Shipping Method', 'Shipping instructions'
]
)
end
context 'as a supplier, with completed order' do
let(:bill_address) { create(:address) }
let(:distributor) { create(:distributor_enterprise) }
let(:distributor1) { create(:distributor_enterprise) }
let(:supplier) { create(:supplier_enterprise) }
let(:user) { create(:admin_user) }
let(:product) { create(:product, supplier:) }
let(:shipping_method) { create(:shipping_method) }
let(:shipping_instructions) { 'pick up on thursday please!' }
let(:order) {
create(:order,
state: 'complete', completed_at: Time.zone.now,
distributor:, bill_address:,
special_instructions: shipping_instructions)
}
let(:payment_method) { create(:payment_method, distributors: [distributor]) }
let(:payment) { create(:payment, payment_method:, order:) }
let(:line_item) { create(:line_item_with_shipment, product:, order:) }
subject { described_class.new user }
before do
order.select_shipping_method(shipping_method.id)
order.payments << payment
order.line_items << line_item
end
it 'should denormalise order and distributor details for display as csv' do
allow(subject).to receive(:unformatted_render?).and_return(true)
table = subject.table_rows
expect(table.size).to eq 1
expect(table[0]).to eq([
order.reload.completed_at.strftime("%F %T"),
order.id,
bill_address.full_name,
order.email,
bill_address.phone,
bill_address.city,
line_item.product.sku,
line_item.product.name,
line_item.options_text,
line_item.quantity,
line_item.max_quantity,
line_item.price * line_item.quantity,
line_item.distribution_fee,
payment_method.name,
distributor.name,
distributor.address.address1,
distributor.address.city,
distributor.address.zipcode,
shipping_method.name,
shipping_instructions
])
end
it "prints one row per line item" do
create(:line_item_with_shipment, order:)
table = subject.table_rows
expect(table.size).to eq 2
end
context "filtering by distributor" do
it do
create(:line_item_with_shipment, order:)
report1 = described_class.new(create(:admin_user), {})
table = report1.table_rows
expect(table.size).to eq 2
report2 = described_class.new(create(:admin_user),
{ q: { distributor_id_in: [distributor.id] } })
table2 = report2.table_rows
expect(table2.size).to eq 2
report3 = described_class.new(create(:admin_user),
{ q: { distributor_id_in: [distributor1.id] } })
table3 = report3.table_rows
expect(table3.size).to eq 0
end
end
context "as a supplier, who has granted P-OC to the distributor" do
let(:user) { create(:enterprise_user, enterprises: [supplier]) }
let(:bill_address) {
create(:address, first_name: "FirstName", last_name: "LastName", phone: "123-456",
city: "City")
}
let(:row) { subject.table_rows.first }
before do
create(:enterprise_relationship, parent: supplier, child: distributor,
permissions_list: [:add_to_order_cycle])
end
it "shows line items supplied by my producers, with contact details hidden" do
expect(row).not_to include("FirstName LastName")
expect(row).not_to include("123-456", "City", order.email)
expect(row[2..5]).to eq ["HIDDEN", "HIDDEN", "", ""]
end
context "where the distributor allows suppliers to see customer names" do
before do
distributor.update_columns show_customer_names_to_suppliers: true
end
context 'with completed order' do
let(:bill_address) { create(:address) }
let(:distributor) { create(:distributor_enterprise) }
let(:distributor1) { create(:distributor_enterprise) }
let(:product) { create(:product) }
let(:shipping_method) { create(:shipping_method) }
let(:shipping_instructions) { 'pick up on thursday please!' }
let(:order) {
create(:order,
state: 'complete', completed_at: Time.zone.now,
distributor:, bill_address:,
special_instructions: shipping_instructions)
}
let(:payment_method) { create(:payment_method, distributors: [distributor]) }
let(:payment) { create(:payment, payment_method:, order:) }
let(:line_item) { create(:line_item_with_shipment, product:, order:) }
before do
order.select_shipping_method(shipping_method.id)
order.payments << payment
order.line_items << line_item
end
it 'should denormalise order and distributor details for display as csv' do
subject = Base.new create(:admin_user), {}
allow(subject).to receive(:unformatted_render?).and_return(true)
table = subject.table_rows
expect(table.size).to eq 1
expect(table[0]).to eq([
order.reload.completed_at.strftime("%F %T"),
order.id,
bill_address.full_name,
order.email,
bill_address.phone,
bill_address.city,
line_item.product.sku,
line_item.product.name,
line_item.options_text,
line_item.quantity,
line_item.max_quantity,
line_item.price * line_item.quantity,
line_item.distribution_fee,
payment_method.name,
distributor.name,
distributor.address.address1,
distributor.address.city,
distributor.address.zipcode,
shipping_method.name,
shipping_instructions
])
end
it "prints one row per line item" do
create(:line_item_with_shipment, order:)
subject = Base.new(create(:admin_user))
table = subject.table_rows
expect(table.size).to eq 2
end
context "filtering by distributor" do
it do
create(:line_item_with_shipment, order:)
report1 = Base.new(create(:admin_user), {})
table = report1.table_rows
expect(table.size).to eq 2
report2 = Base.new(create(:admin_user),
{ q: { distributor_id_in: [distributor.id] } })
table2 = report2.table_rows
expect(table2.size).to eq 2
report3 = Base.new(create(:admin_user),
{ q: { distributor_id_in: [distributor1.id] } })
table3 = report3.table_rows
expect(table3.size).to eq 0
end
end
it "shows line items supplied by my producers, with only contact names shown" do
expect(row).to include("FirstName LastName")
expect(row).not_to include("123-456", "City", order.email)
expect(row[2..5]).to eq [bill_address.full_name, "HIDDEN", "", ""]
end
end
end
it "minimises database queries" do
subject # build context first
expect { subject.table_rows }.to query_database [
"Spree::Role Exists?",
"Spree::Role Exists?",
"SQL",
"Spree::LineItem Load",
"Spree::PaymentMethod Load",
"Spree::Calculator Load",
"Spree::Shipment Load",
"Spree::ShippingRate Load",
"Spree::ShippingMethod Load",
]
end
end
end
end