From 05ed4639b2c9fd73a80a6bb5b20c3b678d9294d4 Mon Sep 17 00:00:00 2001 From: cyrillefr Date: Tue, 23 Jul 2024 15:44:57 +0200 Subject: [PATCH] Fixes 422 error due to bad sql building - first part of query use supplier_properties parameter, but not second part, that can leads to mismatch between the 2 parts. Remove supplier_properties parameter + modify SQL to get it right. - spec tests category filtering & sorting + producer properties --- .../distributed_products_service.rb | 25 +++++++++++++------ spec/services/products_renderer_spec.rb | 13 ++++++++++ 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/app/services/order_cycles/distributed_products_service.rb b/app/services/order_cycles/distributed_products_service.rb index e47ec7a4e3..0b109253eb 100644 --- a/app/services/order_cycles/distributed_products_service.rb +++ b/app/services/order_cycles/distributed_products_service.rb @@ -16,7 +16,7 @@ module OrderCycles end def products_relation_incl_supplier_properties - query = relation_by_sorting(supplier_properties: true) + query = relation_by_sorting query = supplier_property_join(query) @@ -34,10 +34,10 @@ module OrderCycles attr_reader :distributor, :order_cycle, :customer - def relation_by_sorting(supplier_properties: false) + def relation_by_sorting query = Spree::Product.where(id: stocked_products) - if sorting == "by_producer" || supplier_properties + if sorting == "by_producer" # Joins on the first product variant to allow us to filter product by supplier. This is so # enterprise can display product sorted by supplier in a custom order on their shopfront. # @@ -57,7 +57,8 @@ module OrderCycles # different category for a given product. query. joins("LEFT JOIN ( - SELECT DISTINCT ON(product_id) id, product_id, primary_taxon_id + SELECT DISTINCT ON(product_id) id, product_id, primary_taxon_id, + supplier_id FROM spree_variants WHERE deleted_at IS NULL ) first_variant ON spree_products.id = first_variant.product_id"). select("spree_products.*, first_variant.primary_taxon_id"). @@ -71,6 +72,16 @@ module OrderCycles distributor.preferred_shopfront_product_sorting_method end + def sorting_by_producer? + sorting == "by_producer" && + distributor.preferred_shopfront_producer_order.present? + end + + def sorting_by_category? + sorting == "by_category" && + distributor.preferred_shopfront_taxon_order.present? + end + def supplier_property_join(query) query.joins(" JOIN enterprises ON enterprises.id = first_variant.supplier_id @@ -79,16 +90,14 @@ module OrderCycles end def order - if distributor.preferred_shopfront_product_sorting_method == "by_producer" && - distributor.preferred_shopfront_producer_order.present? + if sorting_by_producer? order_by_producer = distributor .preferred_shopfront_producer_order .split(",").map { |id| "first_variant.supplier_id=#{id} DESC" } .join(", ") "#{order_by_producer}, spree_products.name ASC, spree_products.id ASC" - elsif distributor.preferred_shopfront_product_sorting_method == "by_category" && - distributor.preferred_shopfront_taxon_order.present? + elsif sorting_by_category? order_by_category = distributor .preferred_shopfront_taxon_order .split(",").map { |id| "first_variant.primary_taxon_id=#{id} DESC" } diff --git a/spec/services/products_renderer_spec.rb b/spec/services/products_renderer_spec.rb index 170e7b4a2c..19392e248f 100644 --- a/spec/services/products_renderer_spec.rb +++ b/spec/services/products_renderer_spec.rb @@ -155,6 +155,19 @@ RSpec.describe ProductsRenderer do products = products_renderer.send(:products) expect(products).to eq([product_cherries, product_banana_bread, product_doughnuts]) end + + it "filters products with producer properties when sorting is enabled" do + allow(distributor).to receive(:preferred_shopfront_taxon_order) { + "#{fruits.id},#{cakes.id}" + } + fruits_supplier.producer_properties.create!({ property_id: property_organic.id, + value: '1', position: 1 }) + search_param = { q: { "with_variants_supplier_properties" => [property_organic.id] } } + products_renderer = ProductsRenderer.new(distributor, order_cycle, customer, search_param) + + products = products_renderer.send(:products) + expect(products).to eq([product_apples, product_cherries]) + end end end end