diff --git a/engines/dfc_provider/app/controllers/dfc_provider/persons_controller.rb b/engines/dfc_provider/app/controllers/dfc_provider/persons_controller.rb index 977df86adf..f734d188b9 100644 --- a/engines/dfc_provider/app/controllers/dfc_provider/persons_controller.rb +++ b/engines/dfc_provider/app/controllers/dfc_provider/persons_controller.rb @@ -13,8 +13,9 @@ module DfcProvider def affiliate_sales_data render json: DfcIo.export( AffiliateSalesDataBuilder.build_person(user), + *AffiliateSalesDataBuilder.build_order_lines, *AffiliateSalesDataBuilder.build_orders, - *AffiliateSalesDataBuilder.build_sales_session, + *AffiliateSalesDataBuilder.build_sale_sessions, ) end diff --git a/engines/dfc_provider/app/services/affiliate_sales_data_builder.rb b/engines/dfc_provider/app/services/affiliate_sales_data_builder.rb index 16af224db5..bb0fd7e25f 100644 --- a/engines/dfc_provider/app/services/affiliate_sales_data_builder.rb +++ b/engines/dfc_provider/app/services/affiliate_sales_data_builder.rb @@ -1,118 +1,83 @@ # frozen_string_literal: true class AffiliateSalesDataBuilder < DfcBuilder - def self.build_person(user) - DataFoodConsortium::Connector::Person.new( - urls.affiliate_sales_data_person_url(user.id), - logo: nil, - firstName: nil, - lastName: nil, - affiliatedOrganizations: user_enterprises(user.enterprises) - ) - end - - def self.user_enterprises(enterprises) - enterprises.map do |enterprise| - DataFoodConsortium::Connector::Enterprise.new(urls.enterprise_url(enterprise.id)) + class << self + def build_person(user) + DataFoodConsortium::Connector::Person.new( + urls.affiliate_sales_data_person_url(user.id), + logo: nil, + firstName: nil, + lastName: nil, + affiliatedOrganizations: user_enterprises(user.enterprises) + ) end - end - # def self.build_producers - # sales_data.uniq.map do |sale| - # DataFoodConsortium::Connector::Enterprise.new( - # urls.enterprise_url(sale.producer_id), - # name: nil, - # logo: nil, - # description: nil, - # vatNumber: nil - # ) - # end - # end + def user_enterprises(enterprises) + enterprises.map { |enterprise| build_enterprise(enterprise.id) } + end - def self.build_orders - sales_data.map do |sale| + def build_order_lines + sales_data.map { |sale| build_order_line(sale) } + end + + def build_orders + sales_data.map { |sale| build_order(sale) } + end + + def build_sale_sessions + sales_data.map { |sale| build_sale_session(sale) } + end + + private + + def build_enterprise(id) + DataFoodConsortium::Connector::Enterprise.new(urls.enterprise_url(id)) + end + + def build_order_line(sale) + DataFoodConsortium::Connector::OrderLine.new( + urls.enterprise_order_order_line_url(sale.producer_id, sale.order_id, sale.line_item_id), + description: nil, + order: build_order(sale), + quantity: build_quantity(sale), + price: build_price(sale) + ) + end + + def build_order(sale) DataFoodConsortium::Connector::Order.new( urls.enterprise_order_url(sale.producer_id, sale.order_id), number: nil, date: sale.order_date.strftime("%Y-%m-%d"), - saleSession: DataFoodConsortium::Connector::SaleSession.new( - urls.enterprise_sale_session_url(sale.producer_id, sale.order_id), - beginDate: nil, - endDate: nil, - quantity: nil - ) + saleSession: build_sale_session(sale) ) end - end - def self.build_sales_session - sales_data.map do |sale| + def build_sale_session(sale) DataFoodConsortium::Connector::SaleSession.new( - urls.enterprise_sale_session_url(sale.producer_id, sale.order_id), + urls.enterprise_sale_session_url(sale.producer_id, sale.line_item_id), beginDate: nil, endDate: nil, quantity: nil ) end - end - def self.sales_data - @sales_data ||= - Spree::LineItem - .joins(Arel.sql(joins_conditions)) - .select(Arel.sql(select_fields)) - .where(where_conditions) - .group(Arel.sql(group_fields)) - .order(Arel.sql(order_fields)) - end + def build_quantity(sale) + DataFoodConsortium::Connector::Quantity.new( + unit: sale.unit_presentation, + value: sale.line_item_quantity + ) + end - def self.joins_conditions - [ - "JOIN spree_orders ON spree_orders.id = spree_line_items.order_id", - "JOIN spree_variants ON spree_variants.id = spree_line_items.variant_id", - "JOIN spree_products ON spree_products.id = spree_variants.product_id", - "JOIN enterprises AS enterprise1 ON spree_orders.distributor_id = enterprise1.id", - "JOIN enterprises AS enterprise2 ON spree_products.supplier_id = enterprise2.id", - "JOIN spree_addresses AS distributors ON enterprise1.address_id = distributors.id", - "JOIN spree_addresses AS producers ON enterprise2.address_id = producers.id" - ].join(' ') - end + def build_price(sale) + DataFoodConsortium::Connector::Price.new( + value: sale.price.to_f, + unit: sale.currency + ) + end - def self.select_fields - "spree_orders.id AS order_id, - spree_orders.created_at AS order_date, - spree_products.name AS product_name, - spree_variants.display_name AS unit_name, - spree_products.variant_unit AS unit_type, - spree_variants.unit_value AS units, - spree_variants.unit_presentation, - SUM(spree_line_items.quantity) AS quantity_sold, - spree_line_items.price, - producers.id AS producer_id, - distributors.id AS distributor_id, - distributors.zipcode AS distributor_postcode, - producers.zipcode AS producer_postcode" - end - - def self.where_conditions - { spree_orders: { state: 'complete' } } - end - - def self.group_fields - 'spree_orders.id, - spree_products.name, - spree_variants.display_name, - spree_variants.unit_value, - spree_variants.unit_presentation, - spree_products.variant_unit, - spree_line_items.price, - producers.id, - distributors.id, - distributors.zipcode, - producers.zipcode' - end - - def self.order_fields - 'spree_products.name' + def sales_data + @sales_data ||= AffiliateSalesQuery.call + end end end diff --git a/engines/dfc_provider/app/services/affiliate_sales_query.rb b/engines/dfc_provider/app/services/affiliate_sales_query.rb new file mode 100644 index 0000000000..2df2194c05 --- /dev/null +++ b/engines/dfc_provider/app/services/affiliate_sales_query.rb @@ -0,0 +1,64 @@ +class AffiliateSalesQuery + class << self + def call + Spree::LineItem + .joins(sales_data_joins) + .select(sales_data_select) + .where({ spree_orders: { state: 'complete' } }) + .group(sales_data_group) + .order('spree_products.name') + end + + private + + def sales_data_joins + [ + "JOIN spree_orders ON spree_orders.id = spree_line_items.order_id", + "JOIN spree_variants ON spree_variants.id = spree_line_items.variant_id", + "JOIN spree_products ON spree_products.id = spree_variants.product_id", + "JOIN enterprises AS enterprise1 ON spree_orders.distributor_id = enterprise1.id", + "JOIN enterprises AS enterprise2 ON spree_products.supplier_id = enterprise2.id", + "JOIN spree_addresses AS distributors ON enterprise1.address_id = distributors.id", + "JOIN spree_addresses AS producers ON enterprise2.address_id = producers.id" + ].join(' ') + end + + def sales_data_select + <<~SQL.squish + spree_orders.id AS order_id, + spree_orders.created_at AS order_date, + spree_products.name AS product_name, + spree_variants.display_name AS unit_name, + spree_products.variant_unit AS unit_type, + spree_variants.unit_value AS units, + spree_variants.unit_presentation, + spree_line_items.quantity AS line_item_quantity, + SUM(spree_line_items.quantity) AS quantity_sold, + spree_line_items.id AS line_item_id, + spree_line_items.price, + spree_line_items.currency, + producers.id AS producer_id, + distributors.id AS distributor_id, + distributors.zipcode AS distributor_postcode, + producers.zipcode AS producer_postcode + SQL + end + + def sales_data_group + <<~SQL.squish + spree_orders.id, + spree_products.name, + spree_variants.display_name, + spree_variants.unit_value, + spree_variants.unit_presentation, + spree_products.variant_unit, + spree_line_items.id, + spree_line_items.price, + producers.id, + distributors.id, + distributors.zipcode, + producers.zipcode + SQL + end + end +end diff --git a/engines/dfc_provider/config/routes.rb b/engines/dfc_provider/config/routes.rb index a90cf79653..baa404d081 100644 --- a/engines/dfc_provider/config/routes.rb +++ b/engines/dfc_provider/config/routes.rb @@ -8,7 +8,9 @@ DfcProvider::Engine.routes.draw do resources :supplied_products, only: [:create, :show, :update] resources :social_medias, only: [:show] resources :sale_sessions, only: [:show] - resources :orders, only: [:show] + resources :orders, only: [:show] do + resources :order_lines, only: [:show] + end end resources :enterprise_groups, only: [:index, :show] do resources :affiliated_by, only: [:create, :destroy], module: 'enterprise_groups'