mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-24 20:36:49 +00:00
Merge pull request #9032 from seballot/reports-improvement
Reports improvement
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# This configuration was generated by
|
||||
# `rubocop --auto-gen-config --auto-gen-only-exclude --exclude-limit 1400`
|
||||
# on 2022-02-25 01:04:47 UTC using RuboCop version 1.22.2.
|
||||
# on 2022-03-29 16:07:39 UTC using RuboCop version 1.22.2.
|
||||
# The point is for the user to remove these configuration records
|
||||
# one by one as the offenses are removed from the code base.
|
||||
# Note that changes in the inspected code, or installation of new
|
||||
@@ -53,7 +53,7 @@ Layout/LeadingCommentSpace:
|
||||
Exclude:
|
||||
- 'spec/system/admin/enterprises_spec.rb'
|
||||
|
||||
# Offense count: 828
|
||||
# Offense count: 856
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: Max, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
|
||||
# URISchemes: http, https
|
||||
@@ -108,7 +108,6 @@ Layout/LineLength:
|
||||
- 'app/services/order_syncer.rb'
|
||||
- 'app/services/products_renderer.rb'
|
||||
- 'app/services/variant_units/variant_and_line_item_naming.rb'
|
||||
- 'engines/order_management/app/services/order_management/reports/bulk_coop/bulk_coop_report.rb'
|
||||
- 'engines/order_management/app/services/order_management/subscriptions/validator.rb'
|
||||
- 'engines/order_management/spec/services/order_management/order/updater_spec.rb'
|
||||
- 'engines/web/app/helpers/web/cookies_policy_helper.rb'
|
||||
@@ -117,15 +116,19 @@ Layout/LineLength:
|
||||
- 'lib/open_food_network/enterprise_fee_applicator.rb'
|
||||
- 'lib/open_food_network/enterprise_fee_calculator.rb'
|
||||
- 'lib/open_food_network/enterprise_issue_validator.rb'
|
||||
- 'lib/open_food_network/lettuce_share_report.rb'
|
||||
- 'lib/open_food_network/order_cycle_form_applicator.rb'
|
||||
- 'lib/open_food_network/order_cycle_management_report.rb'
|
||||
- 'lib/open_food_network/order_cycle_permissions.rb'
|
||||
- 'lib/open_food_network/payments_report.rb'
|
||||
- 'lib/open_food_network/reports/line_items.rb'
|
||||
- 'lib/open_food_network/sales_tax_report.rb'
|
||||
- 'lib/open_food_network/scope_variants_for_search.rb'
|
||||
- 'lib/open_food_network/xero_invoices_report.rb'
|
||||
- 'lib/reporting/line_items.rb'
|
||||
- 'lib/reporting/reports/bulk_coop/bulk_coop_report.rb'
|
||||
- 'lib/reporting/reports/enterprise_fee_summary/report_data/enterprise_fee_type_total.rb'
|
||||
- 'lib/reporting/reports/order_cycle_management/order_cycle_management_report.rb'
|
||||
- 'lib/open_food_network/order_cycle_permissions.rb'
|
||||
- 'lib/reporting/reports/orders_and_fulfillment/customer_totals_report.rb'
|
||||
- 'lib/reporting/reports/orders_and_fulfillment/distributor_totals_by_supplier_report.rb'
|
||||
- 'lib/reporting/reports/payments/payments_report.rb'
|
||||
- 'lib/reporting/reports/products_and_inventory/lettuce_share_report.rb'
|
||||
- 'lib/reporting/reports/sales_tax/sales_tax_report.rb'
|
||||
- 'lib/reporting/reports/xero_invoices/base.rb'
|
||||
- 'lib/spree/localized_number.rb'
|
||||
- 'lib/tasks/data.rake'
|
||||
- 'lib/tasks/enterprises.rake'
|
||||
@@ -176,19 +179,20 @@ Layout/LineLength:
|
||||
- 'spec/helpers/spree/admin/base_helper_spec.rb'
|
||||
- 'spec/jobs/subscription_confirm_job_spec.rb'
|
||||
- 'spec/jobs/subscription_placement_job_spec.rb'
|
||||
- 'spec/lib/open_food_network/customers_report_spec.rb'
|
||||
- 'spec/lib/open_food_network/enterprise_fee_calculator_spec.rb'
|
||||
- 'spec/lib/open_food_network/group_buy_report_spec.rb'
|
||||
- 'spec/lib/open_food_network/order_cycle_form_applicator_spec.rb'
|
||||
- 'spec/lib/open_food_network/order_cycle_management_report_spec.rb'
|
||||
- 'spec/lib/open_food_network/order_cycle_permissions_spec.rb'
|
||||
- 'spec/lib/open_food_network/order_grouper_spec.rb'
|
||||
- 'spec/lib/open_food_network/permissions_spec.rb'
|
||||
- 'spec/lib/open_food_network/products_and_inventory_report_spec.rb'
|
||||
- 'spec/lib/open_food_network/scope_variant_to_hub_spec.rb'
|
||||
- 'spec/lib/open_food_network/tag_rule_applicator_spec.rb'
|
||||
- 'spec/lib/open_food_network/users_and_enterprises_report_spec.rb'
|
||||
- 'spec/lib/reports/customers_report_spec.rb'
|
||||
- 'spec/lib/reports/order_cycle_management_report_spec.rb'
|
||||
- 'spec/lib/reports/order_grouper_spec.rb'
|
||||
- 'spec/lib/reports/orders_and_fulfillment/orders_and_fulfillment_report_spec.rb'
|
||||
- 'spec/lib/reports/packing/packing_report_spec.rb'
|
||||
- 'spec/lib/reports/products_and_inventory_report_spec.rb'
|
||||
- 'spec/lib/reports/users_and_enterprises_report_spec.rb'
|
||||
- 'spec/lib/reports/xero_invoices_report_spec.rb'
|
||||
- 'spec/lib/stripe/authorize_response_patcher_spec.rb'
|
||||
- 'spec/mailers/order_mailer_spec.rb'
|
||||
- 'spec/mailers/producer_mailer_spec.rb'
|
||||
@@ -309,7 +313,15 @@ Layout/MultilineMethodCallBraceLayout:
|
||||
Exclude:
|
||||
- 'lib/reporting/queries/joins.rb'
|
||||
|
||||
# Offense count: 17
|
||||
# Offense count: 2
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, IndentationWidth.
|
||||
# SupportedStyles: aligned, indented, indented_relative_to_receiver
|
||||
Layout/MultilineMethodCallIndentation:
|
||||
Exclude:
|
||||
- 'lib/reporting/reports/customers/customers_report.rb'
|
||||
|
||||
# Offense count: 20
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: AllowInHeredoc.
|
||||
Layout/TrailingWhitespace:
|
||||
@@ -331,7 +343,7 @@ Lint/ConstantDefinitionInBlock:
|
||||
- 'lib/tasks/users.rake'
|
||||
- 'spec/controllers/spree/admin/base_controller_spec.rb'
|
||||
- 'spec/helpers/serializer_helper_spec.rb'
|
||||
- 'spec/lib/open_food_network/reports/line_items_spec.rb'
|
||||
- 'spec/lib/reports/line_items_spec.rb'
|
||||
- 'spec/models/spree/ability_spec.rb'
|
||||
- 'spec/models/spree/gateway_spec.rb'
|
||||
- 'spec/models/spree/preferences/configuration_spec.rb'
|
||||
@@ -398,7 +410,7 @@ Lint/UselessMethodDefinition:
|
||||
- 'app/controllers/spree/user_registrations_controller.rb'
|
||||
- 'app/models/spree/gateway.rb'
|
||||
|
||||
# Offense count: 39
|
||||
# Offense count: 38
|
||||
# Configuration parameters: IgnoredMethods, CountRepeatedAttributes, Max.
|
||||
Metrics/AbcSize:
|
||||
Exclude:
|
||||
@@ -419,22 +431,21 @@ Metrics/AbcSize:
|
||||
- 'app/models/spree/order/checkout.rb'
|
||||
- 'app/models/spree/preferences/preferable_class_methods.rb'
|
||||
- 'app/models/spree/return_authorization.rb'
|
||||
- 'engines/order_management/app/services/order_management/reports/bulk_coop/bulk_coop_report.rb'
|
||||
- 'lib/discourse/single_sign_on.rb'
|
||||
- 'lib/open_food_network/customers_report.rb'
|
||||
- 'lib/open_food_network/group_buy_report.rb'
|
||||
- 'lib/open_food_network/order_and_distributor_report.rb'
|
||||
- 'lib/open_food_network/order_cycle_form_applicator.rb'
|
||||
- 'lib/reporting/reports/bulk_coop/bulk_coop_report.rb'
|
||||
- 'lib/reporting/reports/customers/customers_report.rb'
|
||||
- 'lib/open_food_network/order_cycle_permissions.rb'
|
||||
- 'lib/open_food_network/payments_report.rb'
|
||||
- 'lib/open_food_network/sales_tax_report.rb'
|
||||
- 'lib/reporting/reports/orders_and_distributors/orders_and_distributors_report.rb'
|
||||
- 'lib/reporting/reports/packing/customer.rb'
|
||||
- 'lib/reporting/reports/payments/payments_report.rb'
|
||||
- 'lib/reporting/reports/sales_tax/sales_tax_report.rb'
|
||||
- 'lib/spree/core/controller_helpers/order.rb'
|
||||
- 'lib/spree/core/s3_support.rb'
|
||||
- 'lib/tasks/enterprises.rake'
|
||||
- 'spec/services/order_checkout_restart_spec.rb'
|
||||
|
||||
# Offense count: 45
|
||||
# Offense count: 43
|
||||
# Configuration parameters: CountComments, Max, CountAsOne, ExcludedMethods, IgnoredMethods.
|
||||
# IgnoredMethods: refine
|
||||
Metrics/BlockLength:
|
||||
@@ -458,13 +469,12 @@ Metrics/BlockLength:
|
||||
- 'spec/factories/subscription_factory.rb'
|
||||
- 'spec/factories/user_factory.rb'
|
||||
- 'spec/factories/variant_factory.rb'
|
||||
- 'spec/lib/open_food_network/group_buy_report_spec.rb'
|
||||
- 'spec/requests/api/orders_spec.rb'
|
||||
- 'spec/spec_helper.rb'
|
||||
- 'spec/swagger_helper.rb'
|
||||
- 'spec/support/cancan_helper.rb'
|
||||
- 'spec/support/matchers/select2_matchers.rb'
|
||||
- 'spec/support/matchers/table_matchers.rb'
|
||||
- 'spec/swagger_helper.rb'
|
||||
- 'spec/system/admin/order_cycles/complex_updating_specific_time_spec.rb'
|
||||
- 'spec/system/consumer/shopping/checkout_spec.rb'
|
||||
|
||||
@@ -474,7 +484,7 @@ Metrics/BlockNesting:
|
||||
Exclude:
|
||||
- 'app/models/spree/payment/processing.rb'
|
||||
|
||||
# Offense count: 49
|
||||
# Offense count: 50
|
||||
# Configuration parameters: CountComments, Max, CountAsOne.
|
||||
Metrics/ClassLength:
|
||||
Exclude:
|
||||
@@ -518,18 +528,17 @@ Metrics/ClassLength:
|
||||
- 'app/services/cart_service.rb'
|
||||
- 'app/services/order_syncer.rb'
|
||||
- 'engines/order_management/app/services/order_management/order/updater.rb'
|
||||
- 'engines/order_management/app/services/order_management/reports/bulk_coop/bulk_coop_report.rb'
|
||||
- 'engines/order_management/app/services/order_management/reports/enterprise_fee_summary/scope.rb'
|
||||
- 'lib/open_food_network/enterprise_fee_calculator.rb'
|
||||
- 'lib/open_food_network/order_cycle_form_applicator.rb'
|
||||
- 'lib/open_food_network/order_cycle_management_report.rb'
|
||||
- 'lib/open_food_network/order_cycle_permissions.rb'
|
||||
- 'lib/open_food_network/payments_report.rb'
|
||||
- 'lib/open_food_network/permissions.rb'
|
||||
- 'lib/open_food_network/users_and_enterprises_report.rb'
|
||||
- 'lib/open_food_network/xero_invoices_report.rb'
|
||||
- 'lib/reporting/reports/bulk_coop/bulk_coop_report.rb'
|
||||
- 'lib/reporting/reports/enterprise_fee_summary/scope.rb'
|
||||
- 'lib/reporting/reports/order_cycle_management/order_cycle_management_report.rb'
|
||||
- 'lib/open_food_network/order_cycle_permissions.rb'
|
||||
- 'lib/reporting/reports/payments/payments_report.rb'
|
||||
- 'lib/reporting/reports/xero_invoices/base.rb'
|
||||
|
||||
# Offense count: 40
|
||||
# Offense count: 39
|
||||
# Configuration parameters: IgnoredMethods, Max.
|
||||
Metrics/CyclomaticComplexity:
|
||||
Exclude:
|
||||
@@ -555,20 +564,19 @@ Metrics/CyclomaticComplexity:
|
||||
- 'app/models/spree/tax_rate.rb'
|
||||
- 'app/models/spree/variant.rb'
|
||||
- 'app/models/spree/zone.rb'
|
||||
- 'engines/order_management/app/services/order_management/reports/bulk_coop/bulk_coop_report.rb'
|
||||
- 'lib/discourse/single_sign_on.rb'
|
||||
- 'lib/open_food_network/customers_report.rb'
|
||||
- 'lib/open_food_network/enterprise_issue_validator.rb'
|
||||
- 'lib/open_food_network/group_buy_report.rb'
|
||||
- 'lib/open_food_network/orders_and_fulfillments_report/customer_totals_report.rb'
|
||||
- 'lib/open_food_network/payments_report.rb'
|
||||
- 'lib/open_food_network/xero_invoices_report.rb'
|
||||
- 'lib/reporting/reports/bulk_coop/bulk_coop_report.rb'
|
||||
- 'lib/reporting/reports/customers/customers_report.rb'
|
||||
- 'lib/reporting/reports/orders_and_fulfillment/customer_totals_report.rb'
|
||||
- 'lib/reporting/reports/payments/payments_report.rb'
|
||||
- 'lib/reporting/reports/xero_invoices/base.rb'
|
||||
- 'lib/spree/core/controller_helpers/order.rb'
|
||||
- 'lib/spree/core/controller_helpers/respond_with.rb'
|
||||
- 'lib/spree/localized_number.rb'
|
||||
- 'spec/models/product_importer_spec.rb'
|
||||
|
||||
# Offense count: 31
|
||||
# Offense count: 32
|
||||
# Configuration parameters: CountComments, Max, CountAsOne, ExcludedMethods, IgnoredMethods.
|
||||
Metrics/MethodLength:
|
||||
Exclude:
|
||||
@@ -578,23 +586,23 @@ Metrics/MethodLength:
|
||||
- 'app/controllers/spree/orders_controller.rb'
|
||||
- 'app/helpers/checkout_helper.rb'
|
||||
- 'app/helpers/spree/admin/navigation_helper.rb'
|
||||
- "app/json_schemas/json_api_schema.rb"
|
||||
- 'app/json_schemas/json_api_schema.rb'
|
||||
- 'app/models/spree/ability.rb'
|
||||
- 'app/models/spree/gateway/pay_pal_express.rb'
|
||||
- 'app/models/spree/order/checkout.rb'
|
||||
- 'app/models/spree/payment/processing.rb'
|
||||
- 'app/models/spree/preferences/preferable_class_methods.rb'
|
||||
- 'engines/order_management/app/services/order_management/reports/bulk_coop/bulk_coop_report.rb'
|
||||
- 'engines/order_management/app/services/order_management/reports/enterprise_fee_summary/scope.rb'
|
||||
- 'lib/discourse/single_sign_on.rb'
|
||||
- 'lib/open_food_network/order_cycle_form_applicator.rb'
|
||||
- 'lib/open_food_network/order_cycle_management_report.rb'
|
||||
- 'lib/reporting/reports/bulk_coop/bulk_coop_report.rb'
|
||||
- 'lib/reporting/reports/enterprise_fee_summary/scope.rb'
|
||||
- 'lib/reporting/reports/order_cycle_management/order_cycle_management_report.rb'
|
||||
- 'lib/open_food_network/order_cycle_permissions.rb'
|
||||
- 'lib/open_food_network/payments_report.rb'
|
||||
- 'lib/open_food_network/xero_invoices_report.rb'
|
||||
- 'lib/reporting/reports/payments/payments_report.rb'
|
||||
- 'lib/reporting/reports/xero_invoices/base.rb'
|
||||
- 'lib/tasks/sample_data/product_factory.rb'
|
||||
|
||||
# Offense count: 51
|
||||
# Offense count: 54
|
||||
# Configuration parameters: CountComments, Max, CountAsOne.
|
||||
Metrics/ModuleLength:
|
||||
Exclude:
|
||||
@@ -625,17 +633,20 @@ Metrics/ModuleLength:
|
||||
- 'spec/controllers/spree/admin/adjustments_controller_spec.rb'
|
||||
- 'spec/controllers/spree/admin/payment_methods_controller_spec.rb'
|
||||
- 'spec/lib/open_food_network/address_finder_spec.rb'
|
||||
- 'spec/lib/open_food_network/customers_report_spec.rb'
|
||||
- 'spec/lib/open_food_network/enterprise_fee_calculator_spec.rb'
|
||||
- 'spec/lib/open_food_network/order_cycle_form_applicator_spec.rb'
|
||||
- 'spec/lib/open_food_network/order_cycle_management_report_spec.rb'
|
||||
- 'spec/lib/open_food_network/order_cycle_permissions_spec.rb'
|
||||
- 'spec/lib/open_food_network/order_grouper_spec.rb'
|
||||
- 'spec/lib/open_food_network/permissions_spec.rb'
|
||||
- 'spec/lib/open_food_network/products_and_inventory_report_spec.rb'
|
||||
- 'spec/lib/open_food_network/scope_variant_to_hub_spec.rb'
|
||||
- 'spec/lib/open_food_network/tag_rule_applicator_spec.rb'
|
||||
- 'spec/lib/open_food_network/users_and_enterprises_report_spec.rb'
|
||||
- 'spec/lib/reports/customers_report_spec.rb'
|
||||
- 'spec/lib/reports/enterprise_fee_summary/authorizer_spec.rb'
|
||||
- 'spec/lib/reports/order_cycle_management_report_spec.rb'
|
||||
- 'spec/lib/reports/order_grouper_spec.rb'
|
||||
- 'spec/lib/reports/orders_and_fulfillment/customer_totals_report_spec.rb'
|
||||
- 'spec/lib/reports/orders_and_fulfillment/orders_and_fulfillment_report_spec.rb'
|
||||
- 'spec/lib/reports/products_and_inventory_report_spec.rb'
|
||||
- 'spec/lib/reports/users_and_enterprises_report_spec.rb'
|
||||
- 'spec/models/spree/adjustment_spec.rb'
|
||||
- 'spec/models/spree/credit_card_spec.rb'
|
||||
- 'spec/models/spree/line_item_spec.rb'
|
||||
@@ -656,11 +667,11 @@ Metrics/ParameterLists:
|
||||
Exclude:
|
||||
- 'app/helpers/angular_form_builder.rb'
|
||||
- 'app/models/product_import/entry_processor.rb'
|
||||
- 'lib/open_food_network/xero_invoices_report.rb'
|
||||
- 'lib/reporting/reports/xero_invoices/base.rb'
|
||||
- 'spec/support/controller_requests_helper.rb'
|
||||
- 'spec/system/admin/reports_spec.rb'
|
||||
|
||||
# Offense count: 8
|
||||
# Offense count: 7
|
||||
# Configuration parameters: IgnoredMethods, Max.
|
||||
Metrics/PerceivedComplexity:
|
||||
Exclude:
|
||||
@@ -669,9 +680,8 @@ Metrics/PerceivedComplexity:
|
||||
- 'app/models/enterprise_relationship.rb'
|
||||
- 'app/models/spree/ability.rb'
|
||||
- 'app/models/spree/order/checkout.rb'
|
||||
- 'engines/order_management/app/services/order_management/reports/bulk_coop/bulk_coop_report.rb'
|
||||
- 'lib/open_food_network/group_buy_report.rb'
|
||||
- 'lib/open_food_network/payments_report.rb'
|
||||
- 'lib/reporting/reports/bulk_coop/bulk_coop_report.rb'
|
||||
- 'lib/reporting/reports/payments/payments_report.rb'
|
||||
|
||||
# Offense count: 9
|
||||
Naming/AccessorMethodName:
|
||||
@@ -716,7 +726,7 @@ Naming/VariableNumber:
|
||||
- 'app/controllers/spree/orders_controller.rb'
|
||||
- 'app/models/content_configuration.rb'
|
||||
- 'app/models/preference_sections/main_links_section.rb'
|
||||
- 'lib/open_food_network/orders_and_fulfillments_report/customer_totals_report.rb'
|
||||
- 'lib/reporting/reports/orders_and_fulfillment/customer_totals_report.rb'
|
||||
- 'lib/spree/core/controller_helpers/common.rb'
|
||||
- 'spec/controllers/spree/admin/search_controller_spec.rb'
|
||||
- 'spec/factories/stock_location_factory.rb'
|
||||
@@ -895,7 +905,7 @@ Rails/LexicallyScopedActionFilter:
|
||||
- 'app/controllers/spree/admin/zones_controller.rb'
|
||||
- 'app/controllers/spree/users_controller.rb'
|
||||
|
||||
# Offense count: 18
|
||||
# Offense count: 19
|
||||
Rails/OutputSafety:
|
||||
Exclude:
|
||||
- 'app/controllers/spree/admin/reports_controller.rb'
|
||||
@@ -1092,9 +1102,9 @@ Style/MissingRespondToMissing:
|
||||
# Offense count: 1
|
||||
Style/MixinUsage:
|
||||
Exclude:
|
||||
- 'lib/open_food_network/orders_and_fulfillments_report.rb'
|
||||
- 'lib/reporting/reports/orders_and_fulfillment/orders_and_fulfillment_report.rb'
|
||||
|
||||
# Offense count: 2
|
||||
# Offense count: 3
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle.
|
||||
# SupportedStyles: literals, strict
|
||||
@@ -1118,7 +1128,7 @@ Style/NestedModifier:
|
||||
- 'spec/system/admin/payments_stripe_spec.rb'
|
||||
- 'spec/system/admin/reports_spec.rb'
|
||||
|
||||
# Offense count: 25
|
||||
# Offense count: 26
|
||||
# Configuration parameters: AllowedMethods.
|
||||
# AllowedMethods: respond_to_missing?
|
||||
Style/OptionalBooleanParameter:
|
||||
@@ -1132,16 +1142,7 @@ Style/OptionalBooleanParameter:
|
||||
- 'app/models/spree/order_contents.rb'
|
||||
- 'app/models/spree/preferences/file_configuration.rb'
|
||||
- 'app/models/spree/shipment.rb'
|
||||
- 'engines/order_management/app/services/order_management/reports/bulk_coop/bulk_coop_report.rb'
|
||||
- 'engines/order_management/app/services/order_management/stock/estimator.rb'
|
||||
- 'lib/open_food_network/customers_report.rb'
|
||||
- 'lib/open_food_network/order_and_distributor_report.rb'
|
||||
- 'lib/open_food_network/order_cycle_management_report.rb'
|
||||
- 'lib/open_food_network/orders_and_fulfillments_report.rb'
|
||||
- 'lib/open_food_network/payments_report.rb'
|
||||
- 'lib/open_food_network/products_and_inventory_report_base.rb'
|
||||
- 'lib/open_food_network/users_and_enterprises_report.rb'
|
||||
- 'lib/open_food_network/xero_invoices_report.rb'
|
||||
- 'lib/spree/core/controller_helpers/order.rb'
|
||||
- 'lib/spree/core/delegate_belongs_to.rb'
|
||||
- 'spec/support/request/web_helper.rb'
|
||||
@@ -1161,11 +1162,10 @@ Style/RedundantReturn:
|
||||
Exclude:
|
||||
- 'app/controllers/spree/admin/shipping_methods_controller.rb'
|
||||
|
||||
# Offense count: 213
|
||||
# Offense count: 205
|
||||
Style/Send:
|
||||
Exclude:
|
||||
- 'app/controllers/split_checkout_controller.rb'
|
||||
- 'engines/order_management/spec/services/order_management/reports/bulk_coop/bulk_coop_report_spec.rb'
|
||||
- 'spec/controllers/admin/subscriptions_controller_spec.rb'
|
||||
- 'spec/controllers/checkout_controller_spec.rb'
|
||||
- 'spec/controllers/payment_gateways/paypal_controller_spec.rb'
|
||||
@@ -1177,13 +1177,10 @@ Style/Send:
|
||||
- 'spec/lib/open_food_network/address_finder_spec.rb'
|
||||
- 'spec/lib/open_food_network/enterprise_fee_applicator_spec.rb'
|
||||
- 'spec/lib/open_food_network/enterprise_fee_calculator_spec.rb'
|
||||
- 'spec/lib/open_food_network/lettuce_share_report_spec.rb'
|
||||
- 'spec/lib/open_food_network/order_cycle_form_applicator_spec.rb'
|
||||
- 'spec/lib/open_food_network/permissions_spec.rb'
|
||||
- 'spec/lib/open_food_network/products_and_inventory_report_spec.rb'
|
||||
- 'spec/lib/open_food_network/sales_tax_report_spec.rb'
|
||||
- 'spec/lib/open_food_network/tag_rule_applicator_spec.rb'
|
||||
- 'spec/lib/open_food_network/xero_invoices_report_spec.rb'
|
||||
- 'spec/lib/reports/xero_invoices_report_spec.rb'
|
||||
- 'spec/lib/stripe/webhook_handler_spec.rb'
|
||||
- 'spec/models/calculator/weight_spec.rb'
|
||||
- 'spec/models/enterprise_spec.rb'
|
||||
@@ -1208,7 +1205,7 @@ Style/SingleArgumentDig:
|
||||
Exclude:
|
||||
- 'app/services/checkout/form_data_adapter.rb'
|
||||
|
||||
# Offense count: 5
|
||||
# Offense count: 4
|
||||
# Cop supports --auto-correct.
|
||||
Style/SlicingWithRange:
|
||||
Exclude:
|
||||
@@ -1216,9 +1213,8 @@ Style/SlicingWithRange:
|
||||
- 'app/services/embedded_page_service.rb'
|
||||
- 'engines/order_management/app/services/order_management/subscriptions/validator.rb'
|
||||
- 'lib/discourse/single_sign_on.rb'
|
||||
- 'spec/lib/open_food_network/order_grouper_spec.rb'
|
||||
|
||||
# Offense count: 31
|
||||
# Offense count: 28
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: Mode.
|
||||
Style/StringConcatenation:
|
||||
@@ -1235,11 +1231,8 @@ Style/StringConcatenation:
|
||||
- 'app/serializers/api/enterprise_shopfront_list_serializer.rb'
|
||||
- 'app/services/embedded_page_service.rb'
|
||||
- 'app/services/products_renderer.rb'
|
||||
- 'engines/order_management/app/services/order_management/reports/bulk_coop/bulk_coop_report.rb'
|
||||
- 'lib/open_food_network/orders_and_fulfillments_report/customer_totals_report.rb'
|
||||
- 'lib/spree/api/controller_setup.rb'
|
||||
- 'lib/spree/core/environment_extension.rb'
|
||||
- 'spec/lib/open_food_network/order_grouper_spec.rb'
|
||||
- 'spec/models/spree/line_item_spec.rb'
|
||||
- 'spec/models/spree/product_spec.rb'
|
||||
- 'spec/models/spree/variant_spec.rb'
|
||||
|
||||
@@ -5,14 +5,23 @@ module Admin
|
||||
include ReportsActions
|
||||
helper ReportsHelper
|
||||
|
||||
before_action :authorize_report
|
||||
before_action :authorize_report, only: [:show]
|
||||
|
||||
# Define model class for Can? permissions
|
||||
def model_class
|
||||
Admin::ReportsController
|
||||
end
|
||||
|
||||
def index
|
||||
@reports = reports.select do |report_type, _description|
|
||||
can? report_type, :report
|
||||
end
|
||||
end
|
||||
|
||||
def show
|
||||
render_report && return if ransack_params.blank?
|
||||
@report = report_class.new(spree_current_user, params, request)
|
||||
|
||||
@report = report_class.new(spree_current_user, ransack_params, report_options)
|
||||
|
||||
if export_spreadsheet?
|
||||
if report_format.present?
|
||||
export_report
|
||||
else
|
||||
render_report
|
||||
@@ -22,33 +31,23 @@ module Admin
|
||||
private
|
||||
|
||||
def export_report
|
||||
render report_format.to_sym => @report.public_send("to_#{report_format}"),
|
||||
:filename => report_filename
|
||||
send_data @report.render_as(report_format, controller: self), filename: report_filename
|
||||
end
|
||||
|
||||
def render_report
|
||||
assign_view_data
|
||||
load_form_options
|
||||
|
||||
render report_type
|
||||
render "show"
|
||||
end
|
||||
|
||||
def assign_view_data
|
||||
@report_type = report_type
|
||||
@report_subtype = report_subtype || report_loader.default_report_subtype
|
||||
@report_subtypes = report_class.report_subtypes.map do |subtype|
|
||||
[t("packing.#{subtype}_report", scope: i18n_scope), subtype]
|
||||
end
|
||||
end
|
||||
@report_subtypes = report_subtypes
|
||||
@report_subtype = report_subtype
|
||||
|
||||
def load_form_options
|
||||
return unless form_options_required?
|
||||
# Initialize data
|
||||
params[:display_summary_row] = true if request.get?
|
||||
|
||||
form_options = Reporting::FrontendData.new(spree_current_user)
|
||||
|
||||
@distributors = form_options.distributors.to_a
|
||||
@suppliers = form_options.suppliers.to_a
|
||||
@order_cycles = form_options.order_cycles.to_a
|
||||
@data = Reporting::FrontendData.new(spree_current_user)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -10,7 +10,8 @@ module Api
|
||||
before_action :validate_report, :authorize_report, :validate_query
|
||||
|
||||
def show
|
||||
@report = report_class.new(current_api_user, ransack_params, report_options)
|
||||
params[:report_format] = 'json'
|
||||
@report = report_class.new(current_api_user, params)
|
||||
|
||||
render_report
|
||||
end
|
||||
|
||||
@@ -3,10 +3,14 @@
|
||||
module ReportsActions
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
def reports
|
||||
Reporting::Reports::List.all
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def authorize_report
|
||||
authorize! report_type&.to_sym, :report
|
||||
authorize! report_type.to_sym, :report
|
||||
end
|
||||
|
||||
def report_class
|
||||
@@ -23,31 +27,26 @@ module ReportsActions
|
||||
params[:report_type]
|
||||
end
|
||||
|
||||
def report_subtypes
|
||||
reports[report_type.to_sym] || []
|
||||
end
|
||||
|
||||
def report_subtypes_codes
|
||||
report_subtypes.map(&:second).map(&:to_s)
|
||||
end
|
||||
|
||||
def report_subtype
|
||||
params[:report_subtype]
|
||||
params[:report_subtype] || report_subtypes_codes.first
|
||||
end
|
||||
|
||||
def ransack_params
|
||||
raw_params[:q]
|
||||
end
|
||||
|
||||
def report_options
|
||||
raw_params[:options]
|
||||
end
|
||||
|
||||
def report_format
|
||||
params[:report_format]
|
||||
end
|
||||
|
||||
def export_spreadsheet?
|
||||
['xlsx', 'ods', 'csv'].include?(report_format)
|
||||
end
|
||||
|
||||
def form_options_required?
|
||||
[:packing, :customers, :products_and_inventory, :order_cycle_management].
|
||||
include? report_type.to_sym
|
||||
end
|
||||
|
||||
def report_filename
|
||||
"#{report_type || action_name}_#{file_timestamp}.#{report_format}"
|
||||
end
|
||||
|
||||
@@ -1,310 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'csv'
|
||||
|
||||
require 'open_food_network/reports/list'
|
||||
require 'open_food_network/order_and_distributor_report'
|
||||
require 'open_food_network/products_and_inventory_report'
|
||||
require 'open_food_network/lettuce_share_report'
|
||||
require 'open_food_network/group_buy_report'
|
||||
require 'open_food_network/order_grouper'
|
||||
require 'open_food_network/customers_report'
|
||||
require 'open_food_network/users_and_enterprises_report'
|
||||
require 'open_food_network/order_cycle_management_report'
|
||||
require 'open_food_network/sales_tax_report'
|
||||
require 'open_food_network/xero_invoices_report'
|
||||
require 'open_food_network/payments_report'
|
||||
require 'open_food_network/orders_and_fulfillments_report'
|
||||
|
||||
module Spree
|
||||
module Admin
|
||||
class ReportsController < Spree::Admin::BaseController
|
||||
include Spree::ReportsHelper
|
||||
helper ::ReportsHelper
|
||||
|
||||
ORDER_MANAGEMENT_ENGINE_REPORTS = [
|
||||
:bulk_coop,
|
||||
:enterprise_fee_summary
|
||||
].freeze
|
||||
|
||||
helper_method :render_content?
|
||||
|
||||
before_action :cache_search_state
|
||||
# Fetches user's distributors, suppliers and order_cycles
|
||||
before_action :load_basic_data, only: [:customers, :products_and_inventory, :order_cycle_management]
|
||||
before_action :load_associated_data, only: [:orders_and_fulfillment]
|
||||
|
||||
respond_to :html
|
||||
|
||||
def report_types
|
||||
OpenFoodNetwork::Reports::List.all
|
||||
end
|
||||
|
||||
def index
|
||||
@reports = authorized_reports
|
||||
respond_with(@reports)
|
||||
end
|
||||
|
||||
def customers
|
||||
@report_types = report_types[:customers]
|
||||
@report_type = params[:report_type]
|
||||
@report = OpenFoodNetwork::CustomersReport.new spree_current_user, raw_params,
|
||||
render_content?
|
||||
render_report(@report.header, @report.table, params[:csv], "customers_#{timestamp}.csv")
|
||||
end
|
||||
|
||||
def order_cycle_management
|
||||
raw_params[:q] ||= {}
|
||||
|
||||
@report_types = report_types[:order_cycle_management]
|
||||
@report_type = params[:report_type]
|
||||
|
||||
# -- Build Report with Order Grouper
|
||||
@report = OpenFoodNetwork::OrderCycleManagementReport.new spree_current_user,
|
||||
raw_params,
|
||||
render_content?
|
||||
@table = @report.table_items
|
||||
|
||||
render_report(@report.header, @table, params[:csv],
|
||||
"order_cycle_management_#{timestamp}.csv")
|
||||
end
|
||||
|
||||
def orders_and_distributors
|
||||
@report = OpenFoodNetwork::OrderAndDistributorReport.new spree_current_user,
|
||||
raw_params,
|
||||
render_content?
|
||||
@search = @report.search
|
||||
csv_file_name = "orders_and_distributors_#{timestamp}.csv"
|
||||
render_report(@report.header, @report.table, params[:csv], csv_file_name)
|
||||
end
|
||||
|
||||
def sales_tax
|
||||
@distributors = my_distributors
|
||||
@report_type = params[:report_type]
|
||||
@report = OpenFoodNetwork::SalesTaxReport.new spree_current_user, raw_params,
|
||||
render_content?
|
||||
render_report(@report.header, @report.table, params[:csv], "sales_tax.csv")
|
||||
end
|
||||
|
||||
def payments
|
||||
# -- Prepare Form Options
|
||||
@distributors = my_distributors
|
||||
@report_type = params[:report_type]
|
||||
|
||||
# -- Build Report with Order Grouper
|
||||
@report = OpenFoodNetwork::PaymentsReport.new spree_current_user, raw_params,
|
||||
render_content?
|
||||
@table = order_grouper_table
|
||||
csv_file_name = "payments_#{timestamp}.csv"
|
||||
|
||||
render_report(@report.header, @table, params[:csv], csv_file_name)
|
||||
end
|
||||
|
||||
def orders_and_fulfillment
|
||||
raw_params[:q] ||= orders_and_fulfillment_default_filters
|
||||
|
||||
@report_types = report_types[:orders_and_fulfillment]
|
||||
@report_type = params[:report_type]
|
||||
|
||||
@include_blank = I18n.t(:all)
|
||||
|
||||
# -- Build Report with Order Grouper
|
||||
@report = OpenFoodNetwork::OrdersAndFulfillmentsReport.new spree_current_user,
|
||||
raw_params,
|
||||
render_content?
|
||||
@table = order_grouper_table
|
||||
csv_file_name = "#{params[:report_type]}_#{timestamp}.csv"
|
||||
|
||||
render_report(@report.header, @table, params[:csv], csv_file_name)
|
||||
end
|
||||
|
||||
def products_and_inventory
|
||||
@report_types = report_types[:products_and_inventory]
|
||||
@report = if params[:report_type] != 'lettuce_share'
|
||||
OpenFoodNetwork::ProductsAndInventoryReport.new spree_current_user,
|
||||
raw_params,
|
||||
render_content?
|
||||
else
|
||||
OpenFoodNetwork::LettuceShareReport.new spree_current_user,
|
||||
raw_params,
|
||||
render_content?
|
||||
end
|
||||
|
||||
render_report @report.header,
|
||||
@report.table,
|
||||
params[:csv],
|
||||
"products_and_inventory_#{timestamp}.csv"
|
||||
end
|
||||
|
||||
def users_and_enterprises
|
||||
@report = OpenFoodNetwork::UsersAndEnterprisesReport.new raw_params, render_content?
|
||||
render_report(@report.header, @report.table, params[:csv],
|
||||
"users_and_enterprises_#{timestamp}.csv")
|
||||
end
|
||||
|
||||
def xero_invoices
|
||||
raw_params[:q] ||= {}
|
||||
|
||||
@distributors = my_distributors
|
||||
@order_cycles = my_order_cycles
|
||||
|
||||
@report = OpenFoodNetwork::XeroInvoicesReport.new(spree_current_user,
|
||||
raw_params,
|
||||
render_content?)
|
||||
render_report(@report.header, @report.table, params[:csv], "xero_invoices_#{timestamp}.csv")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def model_class
|
||||
Spree::Admin::ReportsController
|
||||
end
|
||||
|
||||
# Some actions are changing the `params` object. That is unfortunate Spree
|
||||
# behavior and we are building on it. So we have to look at `params` early
|
||||
# to check if we are searching or just displaying a report search form.
|
||||
def cache_search_state
|
||||
search_keys = [
|
||||
# search parameter for ransack
|
||||
:q,
|
||||
# common in all reports, only set for CSV rendering
|
||||
:csv,
|
||||
# `button` is included in all forms. It's not important for searching,
|
||||
# but the Users & Enterprises report doesn't have any other parameter
|
||||
# for an empty search. So we use this one to display data.
|
||||
:button,
|
||||
# Some reports use filtering by enterprise or order cycle
|
||||
:distributor_id,
|
||||
:supplier_id,
|
||||
:order_cycle_id,
|
||||
# Xero Invoices can be filtered by date
|
||||
:invoice_date,
|
||||
:due_date
|
||||
]
|
||||
@searching = search_keys.any? { |key| raw_params.key? key }
|
||||
end
|
||||
|
||||
# We don't want to render data unless search params are supplied.
|
||||
# Compiling data can take a long time.
|
||||
def render_content?
|
||||
@searching
|
||||
end
|
||||
|
||||
def render_report(header, table, create_csv, csv_file_name)
|
||||
send_data csv_report(header, table), filename: csv_file_name if create_csv
|
||||
@header = header
|
||||
@table = table
|
||||
# Rendering HTML is the default.
|
||||
end
|
||||
|
||||
def load_associated_data
|
||||
form_options = Reporting::FrontendData.new(spree_current_user)
|
||||
|
||||
@distributors = form_options.distributors
|
||||
@suppliers = form_options.suppliers
|
||||
@order_cycles = form_options.order_cycles
|
||||
end
|
||||
|
||||
def csv_report(header, table)
|
||||
CSV.generate do |csv|
|
||||
csv << header
|
||||
table.each { |row| csv << row }
|
||||
end
|
||||
end
|
||||
|
||||
def load_basic_data
|
||||
@distributors = my_distributors
|
||||
@suppliers = my_suppliers | suppliers_of_products_distributed_by(@distributors)
|
||||
@order_cycles = my_order_cycles
|
||||
end
|
||||
|
||||
# Load managed distributor enterprises of current user
|
||||
def my_distributors
|
||||
Enterprise.is_distributor.managed_by(spree_current_user)
|
||||
end
|
||||
|
||||
# Load managed producer enterprises of current user
|
||||
def my_suppliers
|
||||
Enterprise.is_primary_producer.managed_by(spree_current_user)
|
||||
end
|
||||
|
||||
def suppliers_of_products_distributed_by(distributors)
|
||||
supplier_ids = Spree::Product.in_distributors(distributors.select('enterprises.id')).
|
||||
select('spree_products.supplier_id')
|
||||
|
||||
Enterprise.where(id: supplier_ids)
|
||||
end
|
||||
|
||||
# Load order cycles the current user has access to
|
||||
def my_order_cycles
|
||||
OrderCycle.
|
||||
active_or_complete.
|
||||
visible_by(spree_current_user).
|
||||
order('orders_close_at DESC')
|
||||
end
|
||||
|
||||
def order_grouper_table
|
||||
order_grouper = OpenFoodNetwork::OrderGrouper.new @report.rules, @report.columns, @report
|
||||
order_grouper.table(@report.table_items)
|
||||
end
|
||||
|
||||
def authorized_reports
|
||||
all_reports = [
|
||||
:orders_and_distributors,
|
||||
:bulk_coop,
|
||||
:payments,
|
||||
:orders_and_fulfillment,
|
||||
:customers,
|
||||
:products_and_inventory,
|
||||
:users_and_enterprises,
|
||||
:enterprise_fee_summary,
|
||||
:order_cycle_management,
|
||||
:sales_tax,
|
||||
:xero_invoices,
|
||||
:packing
|
||||
]
|
||||
reports = all_reports.select { |action| can? action, Spree::Admin::ReportsController }
|
||||
reports.map { |report| [report, describe_report(report)] }.to_h
|
||||
end
|
||||
|
||||
def describe_report(report)
|
||||
name = I18n.t(:name, scope: [:admin, :reports, report])
|
||||
description = begin
|
||||
I18n.t!(:description, scope: [:admin, :reports, report])
|
||||
rescue I18n::MissingTranslationData
|
||||
render_to_string(
|
||||
partial: "#{report}_description",
|
||||
layout: false,
|
||||
locals: { report_types: report_types[report] }
|
||||
).html_safe
|
||||
end
|
||||
{ name: name, url: url_for_report(report), description: description }
|
||||
end
|
||||
|
||||
def url_for_report(report)
|
||||
if report_in_order_management_engine?(report)
|
||||
main_app.public_send("new_order_management_reports_#{report}_url".to_sym)
|
||||
else
|
||||
spree.public_send("#{report}_admin_reports_url".to_sym)
|
||||
end
|
||||
rescue NoMethodError
|
||||
main_app.admin_reports_url(report_type: report)
|
||||
end
|
||||
|
||||
# List of reports that have been moved to the Order Management engine
|
||||
def report_in_order_management_engine?(report)
|
||||
ORDER_MANAGEMENT_ENGINE_REPORTS.include?(report)
|
||||
end
|
||||
|
||||
def timestamp
|
||||
Time.zone.now.strftime("%Y%m%d")
|
||||
end
|
||||
|
||||
def orders_and_fulfillment_default_filters
|
||||
now = Time.zone.now
|
||||
{ completed_at_gt: (now - 1.month).beginning_of_day,
|
||||
completed_at_lt: (now + 1.day).beginning_of_day }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -9,7 +9,24 @@ module ReportsHelper
|
||||
end
|
||||
end
|
||||
|
||||
def report_subtypes(report)
|
||||
Reporting::ReportLoader.new(report).report_subtypes
|
||||
def report_payment_method_options(orders)
|
||||
orders.map do |order|
|
||||
payment_method = order.payments.last&.payment_method
|
||||
|
||||
next unless payment_method
|
||||
|
||||
[payment_method.name, payment_method.id]
|
||||
end.compact.uniq
|
||||
end
|
||||
|
||||
def report_shipping_method_options(orders)
|
||||
orders.map do |o|
|
||||
sm = o.shipping_method
|
||||
[sm&.name, sm&.id]
|
||||
end.uniq
|
||||
end
|
||||
|
||||
def currency_symbol
|
||||
Spree::Money.currency_symbol
|
||||
end
|
||||
end
|
||||
|
||||
@@ -77,7 +77,7 @@ module Spree
|
||||
klass = EnterpriseGroup if klass == :group
|
||||
klass = VariantOverride if klass == :Inventory
|
||||
klass = ProductImport::ProductImporter if klass == :import
|
||||
klass = Spree::Admin::ReportsController if klass == :report
|
||||
klass = ::Admin::ReportsController if klass == :report
|
||||
klass
|
||||
end
|
||||
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spree/money'
|
||||
|
||||
module Spree
|
||||
module ReportsHelper
|
||||
def report_payment_method_options(orders)
|
||||
orders.map do |order|
|
||||
payment_method = order.payments.last&.payment_method
|
||||
|
||||
next unless payment_method
|
||||
|
||||
[payment_method.name, payment_method.id]
|
||||
end.compact.uniq
|
||||
end
|
||||
|
||||
def report_shipping_method_options(orders)
|
||||
orders.map do |o|
|
||||
sm = o.shipping_method
|
||||
[sm&.name, sm&.id]
|
||||
end.uniq
|
||||
end
|
||||
|
||||
def xero_report_types
|
||||
[[I18n.t(:summary), 'summary'],
|
||||
[I18n.t(:detailed), 'detailed']]
|
||||
end
|
||||
|
||||
def currency_symbol
|
||||
Spree::Money.currency_symbol
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -236,12 +236,10 @@ module Spree
|
||||
:validate_data, :reset_absent_products], ProductImport::ProductImporter
|
||||
|
||||
# Reports page
|
||||
can [:admin, :index, :customers, :orders_and_distributors, :group_buys, :payments,
|
||||
:orders_and_fulfillment, :products_and_inventory, :order_cycle_management, :packing],
|
||||
Spree::Admin::ReportsController
|
||||
can [:admin, :show, :packing], :report
|
||||
add_bulk_coop_abilities
|
||||
add_enterprise_fee_summary_abilities
|
||||
can [:admin, :index, :show], ::Admin::ReportsController
|
||||
can [:admin, :show, :customers, :orders_and_distributors, :group_buys, :payments,
|
||||
:orders_and_fulfillment, :products_and_inventory, :order_cycle_management,
|
||||
:packing, :enterprise_fee_summary, :bulk_coop], :report
|
||||
end
|
||||
|
||||
def add_order_cycle_management_abilities(user)
|
||||
@@ -317,11 +315,10 @@ module Spree
|
||||
end
|
||||
|
||||
# Reports page
|
||||
can [:admin, :index, :customers, :group_buys, :sales_tax, :payments,
|
||||
can [:admin, :index, :show], ::Admin::ReportsController
|
||||
can [:admin, :customers, :group_buys, :sales_tax, :payments,
|
||||
:orders_and_distributors, :orders_and_fulfillment, :products_and_inventory,
|
||||
:order_cycle_management, :xero_invoices], Spree::Admin::ReportsController
|
||||
add_bulk_coop_abilities
|
||||
add_enterprise_fee_summary_abilities
|
||||
:order_cycle_management, :xero_invoices, :enterprise_fee_summary, :bulk_coop], :report
|
||||
|
||||
can [:create], Customer
|
||||
can [:admin, :index, :update,
|
||||
@@ -346,19 +343,5 @@ module Spree
|
||||
user.enterprises.include?(enterprise_relationship.child)
|
||||
end
|
||||
end
|
||||
|
||||
def add_bulk_coop_abilities
|
||||
# Reveal the report link in spree/admin/reports#index
|
||||
can [:bulk_coop], Spree::Admin::ReportsController
|
||||
# Allow direct access to the report resource
|
||||
can [:admin, :new, :create], :bulk_coop
|
||||
end
|
||||
|
||||
def add_enterprise_fee_summary_abilities
|
||||
# Reveal the report link in spree/admin/reports#index
|
||||
can [:enterprise_fee_summary], Spree::Admin::ReportsController
|
||||
# Allow direct access to the report resource
|
||||
can [:admin, :new, :create], :enterprise_fee_summary
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -105,6 +105,10 @@ module Spree
|
||||
render_address([city, zipcode, state&.name])
|
||||
end
|
||||
|
||||
def address_and_city
|
||||
[address1, address2, city].select(&:present?).join(' ')
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def require_zipcode?
|
||||
|
||||
@@ -38,8 +38,13 @@
|
||||
# post.valid? # => false
|
||||
# post.errors[:published_at] # => ["must be valid"]
|
||||
class DateTimeStringValidator < ActiveModel::EachValidator
|
||||
NOT_STRING_ERROR = I18n.t("validators.date_time_string_validator.not_string_error")
|
||||
INVALID_FORMAT_ERROR = I18n.t("validators.date_time_string_validator.invalid_format_error")
|
||||
def self.not_string_error
|
||||
I18n.t("validators.date_time_string_validator.not_string_error")
|
||||
end
|
||||
|
||||
def self.invalid_format_error
|
||||
I18n.t("validators.date_time_string_validator.invalid_format_error")
|
||||
end
|
||||
|
||||
def validate_each(record, attribute, value)
|
||||
return if value.nil? || value == ""
|
||||
@@ -53,13 +58,13 @@ class DateTimeStringValidator < ActiveModel::EachValidator
|
||||
def validate_attribute_is_string(record, attribute, value)
|
||||
return if value.is_a?(String)
|
||||
|
||||
record.errors.add(attribute, NOT_STRING_ERROR)
|
||||
record.errors.add(attribute, DateTimeStringValidator.not_string_error)
|
||||
end
|
||||
|
||||
def validate_attribute_is_datetime_string(record, attribute, value)
|
||||
return unless value.is_a?(String)
|
||||
|
||||
datetime = Time.zone.parse(value)
|
||||
record.errors.add(attribute, INVALID_FORMAT_ERROR) if datetime.blank?
|
||||
record.errors.add(attribute, DateTimeStringValidator.invalid_format_error) if datetime.blank?
|
||||
end
|
||||
end
|
||||
|
||||
@@ -35,8 +35,13 @@
|
||||
# post.valid? # => false
|
||||
# post.errors[:related_post_ids] # => ["must contain only valid integers"]
|
||||
class IntegerArrayValidator < ActiveModel::EachValidator
|
||||
NOT_ARRAY_ERROR = I18n.t("validators.integer_array_validator.not_array_error")
|
||||
INVALID_ELEMENT_ERROR = I18n.t("validators.integer_array_validator.invalid_element_error")
|
||||
def self.not_array_error
|
||||
I18n.t("validators.integer_array_validator.not_array_error")
|
||||
end
|
||||
|
||||
def self.invalid_element_error
|
||||
I18n.t("validators.integer_array_validator.invalid_element_error")
|
||||
end
|
||||
|
||||
def validate_each(record, attribute, value)
|
||||
return if value.nil?
|
||||
@@ -50,7 +55,7 @@ class IntegerArrayValidator < ActiveModel::EachValidator
|
||||
def validate_attribute_is_array(record, attribute, value)
|
||||
return if value.is_a?(Array)
|
||||
|
||||
record.errors.add(attribute, NOT_ARRAY_ERROR)
|
||||
record.errors.add(attribute, IntegerArrayValidator.not_array_error)
|
||||
end
|
||||
|
||||
def validate_attribute_elements_are_integer(record, attribute, array)
|
||||
@@ -60,6 +65,6 @@ class IntegerArrayValidator < ActiveModel::EachValidator
|
||||
Integer(element)
|
||||
end
|
||||
rescue ArgumentError
|
||||
record.errors.add(attribute, INVALID_ELEMENT_ERROR)
|
||||
record.errors.add(attribute, IntegerArrayValidator.invalid_element_error)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
-# Field used for ransack search. This date range is mostly used for Spree::Order
|
||||
-# so default field is 'completed_at'
|
||||
- field ||= 'completed_at'
|
||||
.row.date-range-filter
|
||||
= label_tag nil, t(:date_range)
|
||||
%br
|
||||
= label_tag nil, t(:start), :class => 'inline'
|
||||
= text_field_tag "q[order_completed_at_gt]", params.dig(:q, :order_completed_at_gt), :class => 'datetimepicker datepicker-from'
|
||||
%span.range-divider
|
||||
%i.icon-arrow-right
|
||||
= text_field_tag "q[order_completed_at_lt]", params.dig(:q, :order_completed_at_lt), :class => 'datetimepicker datepicker-to'
|
||||
= label_tag nil, t(:end), :class => 'inline'
|
||||
.alpha.two.columns= label_tag nil, t(:date_range)
|
||||
.omega.fourteen.columns
|
||||
= f.text_field "#{field}_gt", :class => 'datetimepicker datepicker-from', :placeholder => t(:start)
|
||||
%span.range-divider
|
||||
%i.icon-arrow-right
|
||||
= f.text_field "#{field}_lt", :class => 'datetimepicker datepicker-to', :placeholder => t(:stop)
|
||||
|
||||
@@ -1,8 +1,36 @@
|
||||
.row.rendering-options
|
||||
= label_tag :report_format, t(".generate_report")
|
||||
%br
|
||||
= select_tag :report_format, options_for_select({t('.on_screen') => '', t('.csv_spreadsheet') => 'csv', t('.excel_spreadsheet') => 'xlsx', t('.openoffice_spreadsheet') => 'ods'})
|
||||
- if @report_subtypes.present? && @report_subtypes.count > 1
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_type)
|
||||
.omega.fourteen.columns
|
||||
= select_tag(:report_subtype, options_for_select(@report_subtypes, @report_subtype))
|
||||
|
||||
- if @report.header_option? || @report.summary_row_option?
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(".display")
|
||||
.omega.fourteen.columns
|
||||
- if @report.header_option?
|
||||
%span.inline-checkbox{ style: "margin-right: 1rem;" }
|
||||
= check_box_tag :display_header_row, true, params[:display_header_row]
|
||||
= label_tag :display_header_row, t(".header_row")
|
||||
- if @report.summary_row_option?
|
||||
%span.inline-checkbox
|
||||
= check_box_tag :display_summary_row, true, params[:display_summary_row]
|
||||
= label_tag :display_summary_row, t(".summary_row")
|
||||
|
||||
- if @report.available_headers.present?
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_hide_columns)
|
||||
.omega.fourteen.columns
|
||||
= select_tag(:fields_to_hide, options_for_select(@report.available_headers, params[:fields_to_hide]),
|
||||
class: "select2 fullwidth", multiple: true)
|
||||
|
||||
.row.rendering-options
|
||||
.alpha.two.columns
|
||||
= label_tag :report_format, t(".generate_report")
|
||||
.omega.fourteen.columns
|
||||
= select_tag :report_format, grouped_options_for_select({ |
|
||||
t('.formatted_data') => { t('.on_screen') => '', "PDF" => 'pdf', t('.spreadsheet') => 'xlsx' }, |
|
||||
t('.raw_data') => { "CSV" => 'csv', "JSON" => 'json'}, |
|
||||
})
|
||||
|
||||
|
||||
-#.inline-checkbox
|
||||
-# = check_box_tag "options[exclude_summaries]", true, params[:options].andand[:exclude_summaries]
|
||||
-# = label_tag t(".hide_summary_rows")
|
||||
|
||||
22
app/views/admin/reports/_row_group.haml
Normal file
22
app/views/admin/reports/_row_group.haml
Normal file
@@ -0,0 +1,22 @@
|
||||
-# Locals :
|
||||
-# - data
|
||||
-# - report
|
||||
|
||||
- data.each do |group_or_row|
|
||||
- if group_or_row[:is_group].present?
|
||||
/ Header Row
|
||||
- if group_or_row[:header].present? && report.display_header_row?
|
||||
%tr
|
||||
%td.header-row{ colspan: report.table_headers.count, class: group_or_row[:header_class] }
|
||||
= group_or_row[:header].html_safe
|
||||
/ Rows
|
||||
= render partial: 'admin/reports/row_group', locals: { report: report, data: group_or_row[:data] }
|
||||
/ Summary Row
|
||||
- if group_or_row[:summary_row].present? && report.display_summary_row?
|
||||
%tr.summary-row{ class: group_or_row[:summary_row_class] }
|
||||
- group_or_row[:summary_row].to_h.each do |key, value|
|
||||
%td= value
|
||||
- else
|
||||
%tr
|
||||
- group_or_row.row.to_h.each do |key, value|
|
||||
%td= value
|
||||
@@ -1,20 +1,15 @@
|
||||
- if params[:q].present?
|
||||
%table.report__table{id: id}
|
||||
- report ||= @report
|
||||
|
||||
.report__table-container
|
||||
%table.report__table
|
||||
%thead
|
||||
%tr
|
||||
- @report.table_headers.each do |heading|
|
||||
- report.table_headers.each do |heading|
|
||||
%th
|
||||
= t("admin.reports.table.headings.#{heading}")
|
||||
= heading
|
||||
%tbody
|
||||
- @report.table_rows.each do |row|
|
||||
- if row
|
||||
%tr
|
||||
- row.each do |cell|
|
||||
%td
|
||||
= cell
|
||||
- if @report.table_rows.empty?
|
||||
- if report.grouped_data.present?
|
||||
= render partial: 'admin/reports/row_group', locals: { report: report, data: report.grouped_data }
|
||||
- else
|
||||
%tr
|
||||
%td{colspan: @report.table_headers.count}= t(:none)
|
||||
- else
|
||||
%p.report__message
|
||||
= t(".select_and_search", option: msg_option.upcase)
|
||||
%td{colspan: report.table_headers.count}= t(:none)
|
||||
|
||||
6
app/views/admin/reports/filters/_bulk_coop.html.haml
Normal file
6
app/views/admin/reports/filters/_bulk_coop.html.haml
Normal file
@@ -0,0 +1,6 @@
|
||||
= render 'admin/reports/date_range_form', f: f
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_hubs)
|
||||
.omega.fourteen.columns
|
||||
= f.collection_select(:distributor_id_in, @data.distributors, :id, :name, {}, {class: "select2 fullwidth", multiple: true})
|
||||
18
app/views/admin/reports/filters/_customers.html.haml
Normal file
18
app/views/admin/reports/filters/_customers.html.haml
Normal file
@@ -0,0 +1,18 @@
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_customers_distributor)
|
||||
.omega.fourteen.columns
|
||||
= select_tag(:distributor_id,
|
||||
options_from_collection_for_select(@data.distributors, :id, :name, params[:distributor_id]),
|
||||
{:include_blank => true, :class => "select2 fullwidth light"})
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_customers_supplier)
|
||||
.omega.fourteen.columns
|
||||
= select_tag(:supplier_id,
|
||||
options_from_collection_for_select(@data.suppliers, :id, :name, params[:supplier_id]),
|
||||
{:include_blank => true, :class => "select2 fullwidth light"})
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_customers_cycle)
|
||||
.omega.fourteen.columns
|
||||
= select_tag(:order_cycle_id,
|
||||
options_for_select(report_order_cycle_options(@data.order_cycles), params[:order_cycle_id]),
|
||||
{:include_blank => true, :class => "select2 fullwidth light"})
|
||||
@@ -0,0 +1,31 @@
|
||||
= render 'admin/reports/date_range_form', f: f
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_hubs)
|
||||
.omega.fourteen.columns
|
||||
= collection_select(:q, :distributor_ids, @report.permissions.allowed_distributors, :id, :name, {selected: params.dig(:q, :distributor_ids)}, {class: "select2 fullwidth", multiple: true})
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_producers)
|
||||
.omega.fourteen.columns
|
||||
= collection_select(:q, :producer_ids, @report.permissions.allowed_producers, :id, :name, {selected: params.dig(:q, :producer_ids)}, {class: "select2 fullwidth", multiple: true})
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:order_cycles)
|
||||
.omega.fourteen.columns
|
||||
= collection_select(:q, :order_cycle_ids, @report.permissions.allowed_order_cycles, :id, :name, {selected: params.dig(:q, :order_cycle_ids)}, {class: "select2 fullwidth", multiple: true})
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_enterprise_fee)
|
||||
.omega.fourteen.columns
|
||||
= collection_select(:q, :enterprise_fee_ids, @report.permissions.allowed_enterprise_fees, :id, :name, {selected: params.dig(:q, :enterprise_fee_ids)}, {class: "select2 fullwidth", multiple: true})
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t('spree.shipping_methods')
|
||||
.omega.fourteen.columns
|
||||
= collection_select(:q, :shipping_method_ids, @report.permissions.allowed_shipping_methods, :id, :name, {selected: params.dig(:q, :shipping_method_ids)}, {class: "select2 fullwidth", multiple: true})
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_payment)
|
||||
.omega.fourteen.columns
|
||||
= collection_select(:q, :payment_method_ids, @report.permissions.allowed_payment_methods, :id, :name, {selected: params.dig(:q, :payment_method_ids)}, {class: "select2 fullwidth", multiple: true})
|
||||
@@ -0,0 +1,18 @@
|
||||
= render 'admin/reports/date_range_form', f: f
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_hubs)
|
||||
.omega.fourteen.columns= f.collection_select(:distributor_id_in, @data.distributors, :id, :name, {}, {class: "select2 fullwidth", multiple: true})
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_customers_cycle)
|
||||
.omega.fourteen.columns
|
||||
= f.select(:order_cycle_id_in, report_order_cycle_options(@data.order_cycles), {selected: params.dig(:q, :order_cycle_id_in)}, {class: "select2 fullwidth", multiple: true})
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_payment)
|
||||
.omega.fourteen.columns= select_tag(:payment_method_in, options_for_select(report_payment_method_options(@report.query_result), params[:payment_method_in]), {class: "select2 fullwidth", multiple: true})
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:shipping_methods)
|
||||
.omega.fourteen.columns= select_tag(:shipping_method_in, options_for_select(report_shipping_method_options(@report.query_result), params[:shipping_method_in]), {class: "select2 fullwidth", multiple: true})
|
||||
@@ -0,0 +1 @@
|
||||
= render 'admin/reports/date_range_form', f: f
|
||||
14
app/views/admin/reports/filters/_orders_and_fulfillment.html.haml
Executable file
14
app/views/admin/reports/filters/_orders_and_fulfillment.html.haml
Executable file
@@ -0,0 +1,14 @@
|
||||
= render 'admin/reports/date_range_form', f: f
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_hubs)
|
||||
.omega.fourteen.columns= f.collection_select(:distributor_id_in, @data.orders_distributors, :id, :name, {}, {class: "select2 fullwidth", multiple: true})
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_producers)
|
||||
.omega.fourteen.columns= select_tag(:supplier_id_in, options_from_collection_for_select(@data.orders_suppliers, :id, :name, params[:supplier_id_in]), {class: "select2 fullwidth", multiple: true})
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_customers_cycle)
|
||||
.omega.fourteen.columns
|
||||
= f.select(:order_cycle_id_in, report_order_cycle_options(@data.order_cycles), {selected: params.dig(:q, :order_cycle_id_in)}, {class: "select2 fullwidth", multiple: true})
|
||||
16
app/views/admin/reports/filters/_packing.html.haml
Executable file
16
app/views/admin/reports/filters/_packing.html.haml
Executable file
@@ -0,0 +1,16 @@
|
||||
= render partial: 'admin/reports/date_range_form', locals: { f: f, field: 'order_completed_at' }
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_hubs)
|
||||
.omega.fourteen.columns
|
||||
= collection_select("q", "order_distributor_id_in", @data.orders_distributors, :id, :name, {selected: params.dig(:q, :order_distributor_id_in)}, {class: "select2 fullwidth", multiple: true})
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_producers)
|
||||
.omega.fourteen.columns
|
||||
= select_tag("q[supplier_id_in]", options_from_collection_for_select(@data.orders_suppliers, :id, :name, params.dig(:q, :supplier_id_in)), {class: "select2 fullwidth", multiple: true})
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_customers_cycle)
|
||||
.omega.fourteen.columns
|
||||
= select_tag("q[order_cycle_id_in]", options_for_select(report_order_cycle_options(@data.order_cycles), params.dig(:q, :order_cycle_id_in)), {class: "select2 fullwidth", multiple: true})
|
||||
6
app/views/admin/reports/filters/_payments.html.haml
Normal file
6
app/views/admin/reports/filters/_payments.html.haml
Normal file
@@ -0,0 +1,6 @@
|
||||
= render 'admin/reports/date_range_form', f: f
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_distributor)
|
||||
.omega.fourteen.columns
|
||||
= f.collection_select(:distributor_id_eq, @data.distributors, :id, :name, {:include_blank => t(:report_all)}, {:class => "select2 fullwidth light"})
|
||||
@@ -0,0 +1,20 @@
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_distributor)
|
||||
.omega.fourteen.columns
|
||||
= select_tag(:distributor_id,
|
||||
options_from_collection_for_select(@data.distributors, :id, :name, params[:distributor_id]),
|
||||
{:include_blank => true, :class => "select2 fullwidth light"})
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_customers_supplier)
|
||||
.omega.fourteen.columns
|
||||
= select_tag(:supplier_id,
|
||||
options_from_collection_for_select(@data.suppliers, :id, :name, params[:supplier_id]),
|
||||
{:include_blank => true, :class => "select2 fullwidth light"})
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_order_cycle)
|
||||
.omega.fourteen.columns
|
||||
= select_tag(:order_cycle_id,
|
||||
options_for_select(report_order_cycle_options(@data.order_cycles), params[:order_cycle_id]),
|
||||
{:include_blank => true, :class => "select2 fullwidth light"})
|
||||
6
app/views/admin/reports/filters/_sales_tax.html.haml
Normal file
6
app/views/admin/reports/filters/_sales_tax.html.haml
Normal file
@@ -0,0 +1,6 @@
|
||||
= render 'admin/reports/date_range_form', f: f
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_distributor)
|
||||
.omega.fourteen.columns
|
||||
= f.collection_select(:distributor_id_eq, @data.distributors, :id, :name, {:include_blank => t(:all)}, {:class => "select2 fullwidth light"})
|
||||
@@ -0,0 +1,7 @@
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_enterprises)
|
||||
.omega.fourteen.columns= select_tag(:enterprise_id_in, options_from_collection_for_select(Enterprise.all, :id, :name, params[:enterprise_id_in]), {class: "select2 fullwidth", multiple: true})
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_users)
|
||||
.omega.fourteen.columns= select_tag(:user_id_in, options_from_collection_for_select(Spree::User.all, :id, :email, params[:user_id_in]), {class: "select2 fullwidth", multiple: true})
|
||||
25
app/views/admin/reports/filters/_xero_invoices.html.haml
Normal file
25
app/views/admin/reports/filters/_xero_invoices.html.haml
Normal file
@@ -0,0 +1,25 @@
|
||||
= render 'admin/reports/date_range_form', f: f
|
||||
|
||||
.row
|
||||
.two.columns.alpha= label_tag nil, t(:report_hubs)
|
||||
.fourteen.columns.omega= f.collection_select(:distributor_id_eq, @data.distributors, :id, :name, {:include_blank => 'All'}, {:class => "select2 fullwidth light"})
|
||||
.row
|
||||
.two.columns.alpha= label_tag nil, t(:report_order_cycle)
|
||||
.fourteen.columns.omega= f.select(:order_cycle_id_eq,
|
||||
options_for_select(report_order_cycle_options(@data.order_cycles), params.dig(:q, :order_cycle_id_eq)),
|
||||
{:include_blank => true}, {:class => "select2 fullwidth light"})
|
||||
|
||||
%fieldset.no-border-bottom.print-hidden{ style: "padding-bottom: 0" }
|
||||
%legend{ align: 'center'}= t(:report_xero_configuration)
|
||||
.row
|
||||
.two.columns.alpha= label_tag :initial_invoice_number, t(:initial_invoice_number)
|
||||
.fourteen.columns.omega= number_field_tag :initial_invoice_number, params[:initial_invoice_number]
|
||||
.row
|
||||
.two.columns.alpha= label_tag :invoice_date, t(:invoice_date)
|
||||
.fourteen.columns.omega= text_field_tag :invoice_date, params[:invoice_date], class: 'datetimepicker'
|
||||
.row
|
||||
.two.columns.alpha= label_tag :due_date, t(:due_date)
|
||||
.fourteen.columns.omega= text_field_tag :due_date, params[:due_date], class: 'datetimepicker'
|
||||
.row
|
||||
.two.columns.alpha= label_tag :account_code, t(:account_code)
|
||||
.fourteen.columns.omega= text_field_tag :account_code, params[:account_code]
|
||||
25
app/views/admin/reports/index.html.haml
Normal file
25
app/views/admin/reports/index.html.haml
Normal file
@@ -0,0 +1,25 @@
|
||||
- content_for :page_title do
|
||||
= t(:listing_reports)
|
||||
|
||||
.columns.twelve
|
||||
%table.index
|
||||
%thead
|
||||
%tr
|
||||
%th= t(:name)
|
||||
%th= t(:description)
|
||||
%tbody
|
||||
- @reports.each do |report_type, report_subtypes|
|
||||
%tr
|
||||
%td
|
||||
- name = I18n.t(:name, scope: [:admin, :reports, report_type])
|
||||
- url = main_app.admin_report_url(report_type: report_type)
|
||||
= link_to name, url
|
||||
%td
|
||||
- begin
|
||||
= I18n.t!(:description, scope: [:admin, :reports, report_type])
|
||||
- rescue I18n::MissingTranslationData
|
||||
%ul{style: "margin-left: 12pt"}
|
||||
- report_subtypes.each do |report_subtype|
|
||||
%li
|
||||
- url = main_app.admin_report_url(report_type: report_type, report_subtype: report_subtype[1])
|
||||
= link_to report_subtype[0], url
|
||||
@@ -1,31 +0,0 @@
|
||||
= form_tag main_app.admin_reports_path, report_type: 'packing' do
|
||||
= render partial: 'date_range_form'
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_hubs)
|
||||
.omega.fourteen.columns
|
||||
= collection_select("q", "order_distributor_id_in", @distributors, :id, :name, {selected: params.dig(:q, :order_distributor_id_in)}, {class: "select2 fullwidth", multiple: true})
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_producers)
|
||||
.omega.fourteen.columns
|
||||
= select_tag("q[supplier_id_in]", options_from_collection_for_select(@suppliers, :id, :name, params.dig(:q, :supplier_id_in)), {class: "select2 fullwidth", multiple: true})
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_customers_cycle)
|
||||
.omega.fourteen.columns
|
||||
= select_tag("q[order_cycle_id_in]", options_for_select(report_order_cycle_options(@order_cycles), params.dig(:q, :order_cycle_id_in)), {class: "select2 fullwidth", multiple: true})
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_type)
|
||||
.omega.fourteen.columns
|
||||
= select_tag(:report_subtype, options_for_select(@report_subtypes, @report_subtype))
|
||||
|
||||
= render partial: "rendering_options"
|
||||
|
||||
.row
|
||||
= button t(:search)
|
||||
|
||||
= render partial: "spree/admin/reports/customer_names_message"
|
||||
|
||||
= render "table", id: "listing_orders", msg_option: t(:search)
|
||||
22
app/views/admin/reports/show.html.haml
Normal file
22
app/views/admin/reports/show.html.haml
Normal file
@@ -0,0 +1,22 @@
|
||||
= form_for @report.search, :url => url_for(only_path: false) do |f|
|
||||
%fieldset.no-border-bottom.print-hidden
|
||||
%legend{ align: 'center'}= t(:report_filters)
|
||||
= render partial: "admin/reports/filters/#{@report_type}", locals: { f: f }
|
||||
|
||||
%fieldset.print-hidden
|
||||
%legend{ align: 'center'}= t(:report_render_options)
|
||||
= render partial: "rendering_options"
|
||||
|
||||
.actions.filter-actions
|
||||
= button t(:go), "report__submit-btn"
|
||||
|
||||
.report__header.print-hidden
|
||||
- if @report.message.present?
|
||||
%p.report__message= @report.message
|
||||
- if request.post?
|
||||
%button.btn-print.icon-print{ onclick: "window.print()"}= t(:report_print)
|
||||
|
||||
/ We don't want to render data unless search params are supplied.
|
||||
/ Compiling data can take a long time.
|
||||
- if request.post?
|
||||
= render "table"
|
||||
56
app/views/layouts/pdf.html.haml
Normal file
56
app/views/layouts/pdf.html.haml
Normal file
@@ -0,0 +1,56 @@
|
||||
!!!
|
||||
%html
|
||||
%head
|
||||
%meta{charset: 'utf-8'}
|
||||
-# Using wicked_pdf_stylesheet_pack_tag with a new pdf pack was not working when using
|
||||
-# WickedPdf.new.pdf_from_string cause the css file reference was not absolute
|
||||
-# So I ended up putting inline css here, so it's included for sure in the PDF
|
||||
:css
|
||||
body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: system-ui,-apple-system,"Helvetica Neue",Arial,sans-serif;
|
||||
color: #212529;
|
||||
}
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
th {
|
||||
text-align: left;
|
||||
}
|
||||
th, td {
|
||||
padding: 7px 5px;
|
||||
vertical-align: middle;
|
||||
text-overflow: ellipsis;
|
||||
padding-top: 12px;
|
||||
}
|
||||
tr {
|
||||
border-bottom: 1px solid #e2e2e2;
|
||||
}
|
||||
thead {
|
||||
background-color: #f6f6f6;
|
||||
border-bottom: 1px solid grey;
|
||||
}
|
||||
.h1, .h2, .h3 {
|
||||
font-weight: bold;
|
||||
padding-top: 15px;
|
||||
}
|
||||
.h1 {
|
||||
font-size: 1.6rem;
|
||||
padding-top: 20px;
|
||||
}
|
||||
.h2 {
|
||||
font-size: 1.3rem;
|
||||
}
|
||||
.h3 {
|
||||
font-size: 1.15rem;
|
||||
}
|
||||
.text-bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
%body
|
||||
= yield
|
||||
@@ -1,2 +0,0 @@
|
||||
%p.customer-names-tip
|
||||
= t(".customer_names_tip")
|
||||
@@ -1,4 +0,0 @@
|
||||
%ul{style: "margin-left: 12pt"}
|
||||
- report_types.each do |report_type|
|
||||
%li
|
||||
= link_to report_type[0], "#{customers_admin_reports_url}?report_type=#{report_type[1]}"
|
||||
@@ -1,9 +0,0 @@
|
||||
.row.date-range-filter
|
||||
= label_tag nil, t(:date_range)
|
||||
%br
|
||||
= label_tag nil, t(:start), :class => 'inline'
|
||||
= f.text_field :completed_at_gt, :class => 'datetimepicker datepicker-from'
|
||||
%span.range-divider
|
||||
%i.icon-arrow-right
|
||||
= f.text_field :completed_at_lt, :class => 'datetimepicker datepicker-to'
|
||||
= label_tag nil, t(:end), :class => 'inline'
|
||||
@@ -1,2 +0,0 @@
|
||||
- order_number = value
|
||||
= link_to order_number, edit_admin_order_url(order_number), class: 'edit-order'
|
||||
@@ -1,4 +0,0 @@
|
||||
%ul{style: "margin-left: 12pt"}
|
||||
- report_types.each do |report_type|
|
||||
%li
|
||||
= link_to report_type[0], "#{order_cycle_management_admin_reports_url}?report_type=#{report_type[1]}"
|
||||
@@ -1,5 +0,0 @@
|
||||
%ul{style: "margin-left: 12pt"}
|
||||
- report_types.each do |report_type|
|
||||
%li
|
||||
= link_to report_type[0], "#{orders_and_fulfillment_admin_reports_url}?report_type=#{report_type[1]}"
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
%ul{style: "margin-left: 12pt"}
|
||||
- report_subtypes("packing").each do |report_subtype|
|
||||
%li
|
||||
= link_to t("admin.reports.packing.#{report_subtype}_report"),
|
||||
main_app.admin_reports_url(report_type: 'packing', report_subtype: report_subtype)
|
||||
@@ -1,4 +0,0 @@
|
||||
%ul{style: "margin-left: 12pt"}
|
||||
- report_types.each do |report_type|
|
||||
%li
|
||||
= link_to report_type[0], "#{products_and_inventory_admin_reports_url}?report_type=#{report_type[1]}"
|
||||
@@ -1,4 +0,0 @@
|
||||
%ul{style: "margin-left: 12pt"}
|
||||
- report_types.each do |report_type|
|
||||
%li
|
||||
= link_to report_type[0], "#{sales_tax_admin_reports_url}?report_type=#{report_type[1]}"
|
||||
@@ -1,23 +0,0 @@
|
||||
- column_partials ||= {}
|
||||
- if render_content?
|
||||
%table.report__table{id: id}
|
||||
%thead
|
||||
%tr
|
||||
- @header.each do |heading|
|
||||
%th= heading
|
||||
%tbody
|
||||
- @table.each do |row|
|
||||
%tr
|
||||
- row.each_with_index do |cell_value, column_index|
|
||||
%td
|
||||
- partial = column_partials[column_index]
|
||||
- if partial
|
||||
= render partial, value: cell_value
|
||||
- else
|
||||
= cell_value
|
||||
- if @table.empty?
|
||||
%tr
|
||||
%td{colspan: @header.count}= t(:none)
|
||||
- else
|
||||
%p.report__message
|
||||
= t(".select_and_search", option: msg_option.upcase)
|
||||
@@ -1,32 +0,0 @@
|
||||
= form_tag spree.customers_admin_reports_url do |f|
|
||||
%br
|
||||
.row
|
||||
.four.columns.alpha
|
||||
= label_tag nil, t(:report_customers_distributor)
|
||||
= select_tag(:distributor_id,
|
||||
options_from_collection_for_select(@distributors, :id, :name, params[:distributor_id]),
|
||||
{:include_blank => true, :class => "select2 fullwidth"})
|
||||
|
||||
.four.columns
|
||||
= label_tag nil, t(:report_customers_supplier)
|
||||
= select_tag(:supplier_id,
|
||||
options_from_collection_for_select(@suppliers, :id, :name, params[:supplier_id]),
|
||||
{:include_blank => true, :class => "select2 fullwidth"})
|
||||
|
||||
.six.columns
|
||||
= label_tag nil, t(:report_customers_cycle)
|
||||
= select_tag(:order_cycle_id,
|
||||
options_for_select(report_order_cycle_options(@order_cycles), params[:order_cycle_id]),
|
||||
{:include_blank => true, :class => "select2 fullwidth"})
|
||||
|
||||
= label_tag nil, t(:report_customers_type)
|
||||
= select_tag(:report_type, options_for_select(@report_types, @report_type))
|
||||
|
||||
%br
|
||||
%br
|
||||
= check_box_tag :csv
|
||||
= label_tag :csv, t(:report_customers_csv)
|
||||
%br
|
||||
= button t(:go)
|
||||
|
||||
= render "table", id: "listing_customers", msg_option: t(:go)
|
||||
@@ -1,14 +0,0 @@
|
||||
- content_for :page_title do
|
||||
= t(:listing_reports)
|
||||
|
||||
.columns.twelve
|
||||
%table.index
|
||||
%thead
|
||||
%tr
|
||||
%th= t(:name)
|
||||
%th= t(:description)
|
||||
%tbody
|
||||
- @reports.each do |key, value|
|
||||
%tr
|
||||
%td= link_to value[:name], value[:url]
|
||||
%td= value[:description]
|
||||
@@ -1,32 +0,0 @@
|
||||
= form_for @report.search, :url => spree.order_cycle_management_admin_reports_path do |f|
|
||||
= render 'date_range_form', f: f
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_hubs)
|
||||
.omega.fourteen.columns= f.collection_select(:distributor_id_in, @distributors, :id, :name, {}, {class: "select2 fullwidth", multiple: true})
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_customers_cycle)
|
||||
.omega.fourteen.columns
|
||||
= f.select(:order_cycle_id_in, report_order_cycle_options(@order_cycles), {selected: params.dig(:q, :order_cycle_id_in)}, {class: "select2 fullwidth", multiple: true})
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_payment)
|
||||
.omega.fourteen.columns= select_tag(:payment_method_in, options_for_select(report_payment_method_options(@report.orders), params[:payment_method_in]), {class: "select2 fullwidth", multiple: true})
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, "#{t(:shipping_methods)}: "
|
||||
.omega.fourteen.columns= select_tag(:shipping_method_in, options_for_select(report_shipping_method_options(@report.orders), params[:shipping_method_in]), {class: "select2 fullwidth", multiple: true})
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, "#{t(:report_type)}: "
|
||||
.omega.fourteen.columns= select_tag(:report_type, options_for_select(@report_types, @report_type))
|
||||
|
||||
.row
|
||||
= check_box_tag :csv
|
||||
= label_tag :csv, t(:report_customers_csv)
|
||||
|
||||
.row
|
||||
= button t(:search)
|
||||
|
||||
= render "table", id: "listing_ocm_orders", msg_option: t(:search)
|
||||
@@ -1,11 +0,0 @@
|
||||
= form_for @search, :url => spree.orders_and_distributors_admin_reports_path do |f|
|
||||
= render 'date_range_form', f: f
|
||||
|
||||
= check_box_tag :csv
|
||||
= label_tag :csv, t(:report_customers_csv)
|
||||
%br
|
||||
= button t(:search)
|
||||
|
||||
= render partial: "customer_names_message"
|
||||
|
||||
= render "table", id: "listing_orders", msg_option: t(:search)
|
||||
@@ -1,30 +0,0 @@
|
||||
= form_for @report.search, :url => spree.orders_and_fulfillment_admin_reports_path do |f|
|
||||
= render 'date_range_form', f: f
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_hubs)
|
||||
.omega.fourteen.columns= f.collection_select(:distributor_id_in, @distributors, :id, :name, {}, {class: "select2 fullwidth", multiple: true})
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_producers)
|
||||
.omega.fourteen.columns= select_tag(:supplier_id_in, options_from_collection_for_select(@suppliers, :id, :name, params[:supplier_id_in]), {class: "select2 fullwidth", multiple: true})
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_customers_cycle)
|
||||
.omega.fourteen.columns
|
||||
= f.select(:order_cycle_id_in, report_order_cycle_options(@order_cycles), {selected: params.dig(:q, :order_cycle_id_in)}, {class: "select2 fullwidth", multiple: true})
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_type)
|
||||
.omega.fourteen.columns= select_tag(:report_type, options_for_select(@report_types, @report_type))
|
||||
|
||||
.row
|
||||
= check_box_tag :csv
|
||||
= label_tag :csv, t(:report_customers_csv)
|
||||
|
||||
.row
|
||||
= button t(:search)
|
||||
|
||||
= render partial: "customer_names_message"
|
||||
|
||||
= render "table", id: "listing_orders", msg_option: t(:search)
|
||||
@@ -1,19 +0,0 @@
|
||||
= form_for @report.search, :url => spree.payments_admin_reports_path do |f|
|
||||
= render 'date_range_form', f: f
|
||||
|
||||
.row
|
||||
.four.columns.alpha
|
||||
= label_tag nil, t(:report_distributor)
|
||||
= f.collection_select(:distributor_id_eq, @distributors, :id, :name, {:include_blank => t(:report_all)}, {:class => "select2 fullwidth"})
|
||||
= label_tag nil, t(:report_customers_type)
|
||||
%br
|
||||
= select_tag(:report_type, options_for_select([[t(:report_payment_by),:payments_by_payment_type],[t(:report_itemised_payment),:itemised_payment_totals],[t(:report_payment_totals),:payment_totals]], @report_type))
|
||||
%br
|
||||
%br
|
||||
= check_box_tag :csv
|
||||
= label_tag :csv, t(:report_customers_csv)
|
||||
%br
|
||||
%br
|
||||
= button t(:search)
|
||||
|
||||
= render "table", id: "listing_orders", msg_option: t(:search)
|
||||
@@ -1,34 +0,0 @@
|
||||
= form_tag spree.products_and_inventory_admin_reports_url do |f|
|
||||
%br
|
||||
.row
|
||||
.four.columns.alpha
|
||||
= label_tag nil, t(:report_distributor)
|
||||
= select_tag(:distributor_id,
|
||||
options_from_collection_for_select(@distributors, :id, :name, params[:distributor_id]),
|
||||
{:include_blank => true, :class => "select2 fullwidth"})
|
||||
|
||||
|
||||
.four.columns
|
||||
= label_tag nil, t(:report_customers_supplier)
|
||||
= select_tag(:supplier_id,
|
||||
options_from_collection_for_select(@suppliers, :id, :name, params[:supplier_id]),
|
||||
{:include_blank => true, :class => "select2 fullwidth"})
|
||||
|
||||
|
||||
.six.columns
|
||||
= label_tag nil, t(:report_order_cycle)
|
||||
= select_tag(:order_cycle_id,
|
||||
options_for_select(report_order_cycle_options(@order_cycles), params[:order_cycle_id]),
|
||||
{:include_blank => true, :class => "select2 fullwidth"})
|
||||
|
||||
= label_tag nil, t(:report_type)
|
||||
%br
|
||||
= select_tag(:report_type, options_for_select(@report_types, params[:report_type]))
|
||||
|
||||
%br
|
||||
%br
|
||||
= check_box_tag :csv
|
||||
= label_tag :csv, t(:report_customers_csv)
|
||||
%br
|
||||
= button t(:go)
|
||||
= render "table", id: "listing_products", msg_option: t(:go)
|
||||
@@ -1,19 +0,0 @@
|
||||
= form_for @report.search, :url => spree.sales_tax_admin_reports_path do |f|
|
||||
= render 'date_range_form', f: f
|
||||
|
||||
.row
|
||||
.four.columns.alpha
|
||||
= label_tag nil, t(:report_distributor)
|
||||
= f.collection_select(:distributor_id_eq, @distributors, :id, :name, {:include_blank => t(:all)}, {:class => "select2 fullwidth"})
|
||||
= label_tag nil, t(:report_customers_type)
|
||||
%br
|
||||
= select_tag(:report_type, options_for_select([[t(:report_tax_types),:tax_types],[t(:report_tax_rates),:tax_rates]], @report_type))
|
||||
%br
|
||||
%br
|
||||
= check_box_tag :csv
|
||||
= label_tag :csv, t(:report_customers_csv)
|
||||
%br
|
||||
%br
|
||||
= button t(:search)
|
||||
|
||||
= render "table", id: "listing_orders", column_partials: {0 => "link_order"}, msg_option: t(:search)
|
||||
@@ -1,21 +0,0 @@
|
||||
= form_tag spree.users_and_enterprises_admin_reports_url do |f|
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_enterprises)
|
||||
.omega.fourteen.columns= select_tag(:enterprise_id_in, options_from_collection_for_select(Enterprise.all, :id, :name, params[:enterprise_id_in]&.split(",")), {class: "select2 fullwidth", multiple: true})
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_users)
|
||||
.omega.fourteen.columns= select_tag(:user_id_in, options_from_collection_for_select(Spree::User.all, :id, :email, params[:user_id_in]&.split(",")), {class: "select2 fullwidth", multiple: true})
|
||||
|
||||
-# Might need this later if we add different kinds of reports
|
||||
-# .row
|
||||
-# .alpha.two.columns= label_tag nil, "Report Type: "
|
||||
-# .omega.fourteen.columns= select_tag(:report_type, options_for_select(@report_types, params[:report_type]))
|
||||
|
||||
.row
|
||||
= check_box_tag :csv
|
||||
= label_tag :csv, t(:report_customers_csv)
|
||||
.row
|
||||
= button t(:search)
|
||||
|
||||
= render "table", id: "users_and_enterprises", msg_option: t(:search)
|
||||
@@ -1,35 +0,0 @@
|
||||
= form_for @report.search, url: spree.xero_invoices_admin_reports_path do |f|
|
||||
= render 'date_range_form', f: f
|
||||
|
||||
.row
|
||||
.four.columns.alpha= label_tag :report_type, t(:report_type)
|
||||
.four.columns.omega= select_tag :report_type, options_for_select(xero_report_types, params[:report_type]), {include_blank: false, class: "select2 fullwidth"}
|
||||
.row
|
||||
.four.columns.alpha= label_tag nil, t(:report_hubs)
|
||||
.four.columns.omega= f.collection_select(:distributor_id_eq, @distributors, :id, :name, {:include_blank => 'All'}, {:class => "select2 fullwidth"})
|
||||
.row
|
||||
.four.columns.alpha= label_tag nil, t(:report_order_cycle)
|
||||
.four.columns.omega= f.select(:order_cycle_id_eq,
|
||||
options_for_select(report_order_cycle_options(@order_cycles), params.dig(:q, :order_cycle_id_eq)),
|
||||
{:include_blank => true}, {:class => "select2 fullwidth"})
|
||||
|
||||
.row
|
||||
.four.columns.alpha= label_tag :initial_invoice_number, t(:initial_invoice_number)
|
||||
.twelve.columns.omega= text_field_tag :initial_invoice_number, params[:initial_invoice_number]
|
||||
.row
|
||||
.four.columns.alpha= label_tag :invoice_date, t(:invoice_date)
|
||||
.twelve.columns.omega= text_field_tag :invoice_date, params[:invoice_date], class: 'datetimepicker'
|
||||
.row
|
||||
.four.columns.alpha= label_tag :due_date, t(:due_date)
|
||||
.twelve.columns.omega= text_field_tag :due_date, params[:due_date], class: 'datetimepicker'
|
||||
.row
|
||||
.four.columns.alpha= label_tag :account_code, t(:account_code)
|
||||
.twelve.columns.omega= text_field_tag :account_code, params[:account_code]
|
||||
.row
|
||||
.four.columns.alpha= label_tag :csv, t(:report_customers_csv)
|
||||
.twelve.columns.omega= check_box_tag :csv
|
||||
.row
|
||||
.four.columns.alpha= button t(:search)
|
||||
|
||||
|
||||
= render "table", id: "listing_invoices", msg_option: t(:search)
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
%link{:href => "https://fonts.googleapis.com/css?family=Open+Sans:400italic,600italic,400,600&subset=latin,cyrillic,greek,vietnamese", :rel => "stylesheet", :type => "text/css"}
|
||||
|
||||
= stylesheet_pack_tag 'admin-styles'
|
||||
= stylesheet_pack_tag 'admin-styles', media: "screen, print"
|
||||
= render "layouts/bugsnag_js"
|
||||
= javascript_include_tag 'admin/all'
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
= tab :products, :properties, :inventory, :product_import, :images, :variants, :product_properties, :group_buy_options, :seo, url: admin_products_path, icon: 'icon-th-large'
|
||||
= tab :order_cycles, url: main_app.admin_order_cycles_path, icon: 'icon-refresh'
|
||||
= tab :orders, :subscriptions, :customer_details, :adjustments, :payments, :return_authorizations, url: admin_orders_path('q[s]' => 'completed_at desc'), icon: 'icon-shopping-cart'
|
||||
= tab :reports, icon: 'icon-file'
|
||||
= tab :reports, url: main_app.admin_reports_path, icon: 'icon-file'
|
||||
= tab :general_settings, :mail_methods, :tax_categories, :tax_rates, :tax_settings, :zones, :countries, :states, :payment_methods, :taxonomies, :shipping_methods, :shipping_categories, :enterprise_fees, :contents, :invoice_settings, :matomo_settings, :stripe_connect_settings, label: 'configuration', icon: 'icon-wrench', url: edit_admin_general_settings_path
|
||||
= tab :enterprises, :enterprise_relationships, url: main_app.admin_enterprises_path
|
||||
= tab :customers, url: main_app.admin_customers_path
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
.date-range-filter {
|
||||
.range-divider {
|
||||
padding: 0;
|
||||
margin-left: 5px;
|
||||
}
|
||||
input.datepicker {
|
||||
width: 96px !important;
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.text-bold{
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.underline {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
@@ -1,29 +1,62 @@
|
||||
.report__table {
|
||||
margin-top: 2em;
|
||||
table.report__table {
|
||||
margin-top: 1em;
|
||||
@media print {
|
||||
margin: 0;
|
||||
td, th {
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
}
|
||||
}
|
||||
thead th {
|
||||
text-align: left;
|
||||
padding: 10px 6px;
|
||||
}
|
||||
|
||||
.header-row {
|
||||
&.h1, &.h2, &.h3 {
|
||||
font-weight: bold;
|
||||
margin-top: 8px;
|
||||
}
|
||||
&.h1 {
|
||||
font-size: 2em;
|
||||
}
|
||||
&.h2 {
|
||||
font-size: 1.5em;
|
||||
}
|
||||
&.h3 {
|
||||
font-size: 1.25em;
|
||||
}
|
||||
&.h4 {
|
||||
font-size: 1;
|
||||
}
|
||||
&.with-background {
|
||||
background-color: #eef5fc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.report__message {
|
||||
.report__header {
|
||||
display: flex;
|
||||
margin-top: 2em;
|
||||
border: 1px solid $pale-blue;
|
||||
border-radius: .5em;
|
||||
padding: .5em;
|
||||
text-align: center;
|
||||
justify-content: flex-end;
|
||||
|
||||
.btn-print {
|
||||
margin-left: 1em;
|
||||
}
|
||||
.report__message {
|
||||
border: 1px solid $pale-blue;
|
||||
border-radius: .5em;
|
||||
padding: .5em;
|
||||
text-align: center;
|
||||
flex-grow: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.customer-names-tip {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.rendering-options {
|
||||
select {
|
||||
display: block;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.inline-checkbox {
|
||||
line-height: 2.5em;
|
||||
margin-left: 1em;
|
||||
display: block;
|
||||
float: left;
|
||||
}
|
||||
.report__submit-btn {
|
||||
margin: 0 !important;
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
@@ -242,3 +242,17 @@ select {
|
||||
@extend input, [type="text"];
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.inline-checkbox {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
margin-top: 3px;
|
||||
|
||||
input, label {
|
||||
cursor: pointer;
|
||||
}
|
||||
label {
|
||||
margin: 0;
|
||||
padding-left: .4rem;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,6 +68,11 @@
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
@media print {
|
||||
.print-hidden {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
// Header
|
||||
//---------------------------------------------------
|
||||
@@ -103,3 +108,9 @@
|
||||
border-top: 1px solid $color-border;
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
@media print {
|
||||
header, nav {
|
||||
display:none;
|
||||
}
|
||||
}
|
||||
@@ -160,16 +160,6 @@ en:
|
||||
withdrawal_count_limit_exceeded: "The customer has exceeded the balance or credit limit available on their card."
|
||||
|
||||
activemodel:
|
||||
attributes:
|
||||
order_management/reports/enterprise_fee_summary/parameters:
|
||||
start_at: "Start"
|
||||
end_at: "End"
|
||||
distributor_ids: "Hubs"
|
||||
producer_ids: "Producers"
|
||||
order_cycle_ids: "Order Cycles"
|
||||
enterprise_fee_ids: "Fees Names"
|
||||
shipping_method_ids: "Shipping Methods"
|
||||
payment_method_ids: "Payment Methods"
|
||||
errors:
|
||||
messages:
|
||||
inclusion: "is not included in the list"
|
||||
@@ -1265,6 +1255,8 @@ en:
|
||||
unitsize: UNITSIZE
|
||||
total: TOTAL
|
||||
total_items: TOTAL ITEMS
|
||||
total_by_customer: Total By Customer
|
||||
total_by_supplier: Total By Supplier
|
||||
supplier_totals: Order Cycle Supplier Totals
|
||||
supplier_totals_by_distributor: Order Cycle Supplier Totals by Distributor
|
||||
totals_by_supplier: Order Cycle Distributor Totals by Supplier
|
||||
@@ -1280,6 +1272,7 @@ en:
|
||||
tax_rates: Tax Rates
|
||||
pack_by_customer: Pack By Customer
|
||||
pack_by_supplier: Pack By Supplier
|
||||
pack_by_product: Pack By Product
|
||||
orders_and_distributors:
|
||||
name: Orders And Distributors
|
||||
description: Orders with distributor details
|
||||
@@ -1295,7 +1288,6 @@ en:
|
||||
name: Customers
|
||||
products_and_inventory:
|
||||
name: Products & Inventory
|
||||
description:
|
||||
users_and_enterprises:
|
||||
name: Users & Enterprises
|
||||
description: Enterprise Ownership & Status
|
||||
@@ -1329,17 +1321,18 @@ en:
|
||||
quantity: "Quantity"
|
||||
is_temperature_controlled: "TempControlled?"
|
||||
temp_controlled: "TempControlled?"
|
||||
price: "Price"
|
||||
rendering_options:
|
||||
generate_report: "Generate report:"
|
||||
generate_report: "Generate report"
|
||||
on_screen: "On screen"
|
||||
csv_spreadsheet: "CSV Spreadsheet"
|
||||
excel_spreadsheet: "Excel Spreadsheet"
|
||||
openoffice_spreadsheet: "OpenOffice Spreadsheet"
|
||||
hide_summary_rows: "Hide summary Rows"
|
||||
spreadsheet: "Spreadsheet (Excel, OpenOffice..)"
|
||||
display: Display
|
||||
summary_row: Summary Row
|
||||
header_row: Header Row
|
||||
raw_data: Raw Data
|
||||
formatted_data: Formatted Data
|
||||
packing:
|
||||
name: "Packing Reports"
|
||||
customer_report: "Pack By Customer"
|
||||
supplier_report: "Pack By Supplier"
|
||||
subscriptions:
|
||||
index:
|
||||
title: "Subscriptions"
|
||||
@@ -2622,20 +2615,25 @@ See the %{link} to find out more about %{sitename}'s features and to start using
|
||||
report_customers_cycle: "Order Cycle"
|
||||
report_customers_type: "Report Type"
|
||||
report_customers_csv: "Download as csv"
|
||||
report_producers: "Producers: "
|
||||
report_type: "Report Type: "
|
||||
report_hubs: "Hubs: "
|
||||
report_payment: "Payment Methods: "
|
||||
report_distributor: "Distributor: "
|
||||
report_producers: "Producers"
|
||||
report_type: "Report Type"
|
||||
report_hubs: "Hubs"
|
||||
report_payment: "Payment Methods"
|
||||
report_distributor: "Distributor"
|
||||
report_payment_by: 'Payments By Type'
|
||||
report_itemised_payment: 'Itemised Payment Totals'
|
||||
report_payment_totals: 'Payment Totals'
|
||||
report_all: 'all'
|
||||
report_order_cycle: "Order Cycle: "
|
||||
report_enterprises: "Enterprises: "
|
||||
report_users: "Users: "
|
||||
report_order_cycle: "Order Cycle"
|
||||
report_hide_columns: Columns to Hide
|
||||
report_enterprises: "Enterprises"
|
||||
report_enterprise_fee: "Fees Names"
|
||||
report_users: "Users"
|
||||
report_tax_rates: Tax rates
|
||||
report_tax_types: Tax types
|
||||
report_filters: Report Filters
|
||||
report_print: Print Report
|
||||
report_render_options: Rendering Options
|
||||
report_header_order_cycle: Order Cycle
|
||||
report_header_user: User
|
||||
report_header_email: Email
|
||||
@@ -2771,10 +2769,11 @@ See the %{link} to find out more about %{sitename}'s features and to start using
|
||||
report_header_transaction_fee: Transaction Fee (no tax)
|
||||
report_header_total_untaxable_admin: Total untaxable admin adjustments (no tax)
|
||||
report_header_total_taxable_admin: Total taxable admin adjustments (tax inclusive)
|
||||
initial_invoice_number: "Initial invoice number:"
|
||||
invoice_date: "Invoice date:"
|
||||
due_date: "Due date:"
|
||||
account_code: "Account code:"
|
||||
report_xero_configuration: Xero Configuration
|
||||
initial_invoice_number: "Initial invoice number"
|
||||
invoice_date: "Invoice date"
|
||||
due_date: "Due date"
|
||||
account_code: "Account code"
|
||||
equals: "Equals"
|
||||
contains: "contains"
|
||||
discount: "Discount"
|
||||
@@ -3310,9 +3309,6 @@ See the %{link} to find out more about %{sitename}'s features and to start using
|
||||
bulk_coop_customer_payments: "Bulk Co-op Customer Payments"
|
||||
bulk_coop_packing_sheets: "Bulk Co-op Packing Sheets"
|
||||
bulk_coop_supplier_report: "Bulk Co-op Supplier Report"
|
||||
date_range: "Date range"
|
||||
generate_report: "Generate Report"
|
||||
report_format_csv: "Report format CSV"
|
||||
enterprise_fee_summaries:
|
||||
filters:
|
||||
date_range: "Date Range"
|
||||
@@ -3954,11 +3950,6 @@ See the %{link} to find out more about %{sitename}'s features and to start using
|
||||
reports:
|
||||
table:
|
||||
select_and_search: "Select filters and click on %{option} to access your data."
|
||||
bulk_coop:
|
||||
bulk_coop_supplier_report: 'Bulk Co-op - Totals by Supplier'
|
||||
bulk_coop_allocation: 'Bulk Co-op - Allocation'
|
||||
bulk_coop_packing_sheets: 'Bulk Co-op - Packing Sheets'
|
||||
bulk_coop_customer_payments: 'Bulk Co-op - Customer Payments'
|
||||
customer_names_message:
|
||||
customer_names_tip: "If customer names are hidden for orders you have supplied, you can contact the distributor and ask if they can update their shop preferences to allow their suppliers to view customer names."
|
||||
users:
|
||||
|
||||
@@ -115,6 +115,7 @@ Openfoodnetwork::Application.routes.draw do
|
||||
put :resume, on: :member, format: :json
|
||||
end
|
||||
|
||||
match '/reports/:report_type(/:report_subtype)', to: 'reports#show', via: [:get, :post], as: :reports
|
||||
get '/reports', to: 'reports#index', as: :reports
|
||||
match '/reports/:report_type(/:report_subtype)', to: 'reports#show', via: [:get, :post], as: :report
|
||||
end
|
||||
end
|
||||
|
||||
@@ -31,18 +31,6 @@ Spree::Core::Engine.routes.draw do
|
||||
|
||||
resource :account, :controller => 'users'
|
||||
|
||||
match '/admin/reports/orders_and_distributors' => 'admin/reports#orders_and_distributors', :as => "orders_and_distributors_admin_reports", :via => [:get, :post]
|
||||
match '/admin/reports/order_cycle_management' => 'admin/reports#order_cycle_management', :as => "order_cycle_management_admin_reports", :via => [:get, :post]
|
||||
match '/admin/reports/group_buys' => 'admin/reports#group_buys', :as => "group_buys_admin_reports", :via => [:get, :post]
|
||||
match '/admin/reports/bulk_coop' => 'admin/reports#bulk_coop', :as => "bulk_coop_admin_reports", :via => [:get, :post]
|
||||
match '/admin/reports/payments' => 'admin/reports#payments', :as => "payments_admin_reports", :via => [:get, :post]
|
||||
match '/admin/reports/orders_and_fulfillment' => 'admin/reports#orders_and_fulfillment', :as => "orders_and_fulfillment_admin_reports", :via => [:get, :post]
|
||||
match '/admin/reports/users_and_enterprises' => 'admin/reports#users_and_enterprises', :as => "users_and_enterprises_admin_reports", :via => [:get, :post]
|
||||
match '/admin/reports/sales_tax' => 'admin/reports#sales_tax', :as => "sales_tax_admin_reports", :via => [:get, :post]
|
||||
match '/admin/reports/products_and_inventory' => 'admin/reports#products_and_inventory', :as => "products_and_inventory_admin_reports", :via => [:get, :post]
|
||||
match '/admin/reports/customers' => 'admin/reports#customers', :as => "customers_admin_reports", :via => [:get, :post]
|
||||
match '/admin/reports/xero_invoices' => 'admin/reports#xero_invoices', :as => "xero_invoices_admin_reports", :via => [:get, :post]
|
||||
|
||||
match '/admin/orders/bulk_management' => 'admin/orders#bulk_management', :as => "admin_bulk_order_management", via: :get
|
||||
match '/admin/payment_methods/show_provider_preferences' => 'admin/payment_methods#show_provider_preferences', :via => :get
|
||||
put 'credit_cards/new_from_token', to: 'credit_cards#new_from_token'
|
||||
@@ -126,8 +114,6 @@ Spree::Core::Engine.routes.draw do
|
||||
end
|
||||
end
|
||||
|
||||
resources :reports, only: :index
|
||||
|
||||
resources :users do
|
||||
member do
|
||||
put :generate_api_key
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module OrderManagement
|
||||
module Reports
|
||||
class BulkCoopController < Spree::Admin::BaseController
|
||||
before_action :load_report_parameters
|
||||
before_action :load_permissions
|
||||
|
||||
def new; end
|
||||
|
||||
def create
|
||||
return respond_to_invalid_parameters unless @report_parameters.valid?
|
||||
|
||||
@report_parameters.authorize!(@permissions)
|
||||
|
||||
@report = report_klass::ReportService.new(@permissions, legacy_format_report_params,
|
||||
spree_current_user)
|
||||
renderer.render(self)
|
||||
rescue ::Reports::Authorizer::ParameterNotAllowedError => e
|
||||
flash[:error] = e.message
|
||||
render_report_form
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def respond_to_invalid_parameters
|
||||
flash[:error] = I18n.t("invalid_filter_parameters", scope: i18n_scope)
|
||||
render_report_form
|
||||
end
|
||||
|
||||
def i18n_scope
|
||||
"order_management.reports.enterprise_fee_summary"
|
||||
end
|
||||
|
||||
def render_report_form
|
||||
render action: :new
|
||||
end
|
||||
|
||||
def report_klass
|
||||
OrderManagement::Reports::BulkCoop
|
||||
end
|
||||
|
||||
def legacy_format_report_params
|
||||
{
|
||||
q: {
|
||||
completed_at_gt: params[:report][:start_at],
|
||||
completed_at_lt: params[:report][:end_at],
|
||||
distributor_id_in: params[:report][:distributor_ids],
|
||||
},
|
||||
report_type: params[:report][:report_type]
|
||||
}
|
||||
end
|
||||
|
||||
def load_report_parameters
|
||||
@report_parameters = report_klass::Parameters.new(params[:report] || {})
|
||||
end
|
||||
|
||||
def load_permissions
|
||||
@permissions = report_klass::Permissions.new(spree_current_user)
|
||||
end
|
||||
|
||||
def report_renderer_klass
|
||||
case params[:report_format]
|
||||
when "csv"
|
||||
report_klass::Renderers::CsvRenderer
|
||||
when nil, "", "html"
|
||||
report_klass::Renderers::HtmlRenderer
|
||||
else
|
||||
raise Reports::UnsupportedReportFormatException
|
||||
end
|
||||
end
|
||||
|
||||
def renderer
|
||||
@renderer ||= report_renderer_klass.new(@report)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,66 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module OrderManagement
|
||||
module Reports
|
||||
class EnterpriseFeeSummariesController < Spree::Admin::BaseController
|
||||
before_action :load_report_parameters
|
||||
before_action :load_permissions
|
||||
|
||||
def new; end
|
||||
|
||||
def create
|
||||
return respond_to_invalid_parameters unless @report_parameters.valid?
|
||||
|
||||
@report_parameters.authorize!(@permissions)
|
||||
|
||||
@report = report_klass::ReportService.new(@permissions, @report_parameters)
|
||||
renderer.render(self)
|
||||
rescue ::Reports::Authorizer::ParameterNotAllowedError => e
|
||||
flash[:error] = e.message
|
||||
render_report_form
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def respond_to_invalid_parameters
|
||||
flash[:error] = I18n.t("invalid_filter_parameters", scope: i18n_scope)
|
||||
render_report_form
|
||||
end
|
||||
|
||||
def i18n_scope
|
||||
"order_management.reports.enterprise_fee_summary"
|
||||
end
|
||||
|
||||
def render_report_form
|
||||
render action: :new
|
||||
end
|
||||
|
||||
def report_klass
|
||||
OrderManagement::Reports::EnterpriseFeeSummary
|
||||
end
|
||||
|
||||
def load_report_parameters
|
||||
@report_parameters = report_klass::Parameters.new(params[:report] || {})
|
||||
end
|
||||
|
||||
def load_permissions
|
||||
@permissions = report_klass::Permissions.new(spree_current_user)
|
||||
end
|
||||
|
||||
def report_renderer_klass
|
||||
case params[:report_format]
|
||||
when "csv"
|
||||
report_klass::Renderers::CsvRenderer
|
||||
when nil, "", "html"
|
||||
report_klass::Renderers::HtmlRenderer
|
||||
else
|
||||
raise Reports::UnsupportedReportFormatException
|
||||
end
|
||||
end
|
||||
|
||||
def renderer
|
||||
@renderer ||= report_renderer_klass.new(@report)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,13 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module OrderManagement
|
||||
module Reports
|
||||
module BulkCoop
|
||||
class Authorizer < ::Reports::Authorizer
|
||||
def authorize!
|
||||
require_ids_allowed(parameters.distributor_ids, permissions.allowed_distributors)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,67 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module OrderManagement
|
||||
module Reports
|
||||
module BulkCoop
|
||||
class BulkCoopAllocationReport
|
||||
def header
|
||||
[
|
||||
I18n.t(:report_header_customer),
|
||||
I18n.t(:report_header_product),
|
||||
I18n.t(:report_header_bulk_unit_size),
|
||||
I18n.t(:report_header_variant),
|
||||
I18n.t(:report_header_variant_value),
|
||||
I18n.t(:report_header_variant_unit),
|
||||
I18n.t(:report_header_weight),
|
||||
I18n.t(:report_header_sum_total),
|
||||
I18n.t(:report_header_total_available),
|
||||
I18n.t(:report_header_unallocated),
|
||||
I18n.t(:report_header_max_quantity_excess),
|
||||
]
|
||||
end
|
||||
|
||||
def rules
|
||||
[
|
||||
{
|
||||
group_by: proc { |line_item| line_item.product },
|
||||
sort_by: proc { |product| product.name },
|
||||
summary_columns: [
|
||||
:total_label,
|
||||
:variant_product_name,
|
||||
:variant_product_group_buy_unit_size_f,
|
||||
:empty_cell,
|
||||
:empty_cell,
|
||||
:empty_cell,
|
||||
:empty_cell,
|
||||
:total_amount,
|
||||
:total_available,
|
||||
:remainder,
|
||||
:max_quantity_excess
|
||||
]
|
||||
},
|
||||
{
|
||||
group_by: proc { |line_item| line_item.order },
|
||||
sort_by: proc { |order| order.to_s }
|
||||
}
|
||||
]
|
||||
end
|
||||
|
||||
def columns
|
||||
[
|
||||
:order_billing_address_name,
|
||||
:product_name,
|
||||
:product_group_buy_unit_size,
|
||||
:full_name,
|
||||
:option_value_value,
|
||||
:option_value_unit,
|
||||
:weight_from_unit_value,
|
||||
:total_amount,
|
||||
:empty_cell,
|
||||
:empty_cell,
|
||||
:empty_cell
|
||||
]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,323 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "open_food_network/reports/line_items"
|
||||
|
||||
module OrderManagement
|
||||
module Reports
|
||||
module BulkCoop
|
||||
class BulkCoopReport
|
||||
REPORT_TYPES = [
|
||||
:bulk_coop_supplier_report,
|
||||
:bulk_coop_allocation,
|
||||
:bulk_coop_packing_sheets,
|
||||
:bulk_coop_customer_payments
|
||||
].freeze
|
||||
|
||||
attr_reader :params
|
||||
|
||||
def initialize(user, params = {}, render_table = false)
|
||||
@params = params
|
||||
@user = user
|
||||
@render_table = render_table
|
||||
|
||||
@supplier_report = BulkCoopSupplierReport.new
|
||||
@allocation_report = BulkCoopAllocationReport.new
|
||||
@filter_canceled = false
|
||||
end
|
||||
|
||||
def header
|
||||
case params[:report_type]
|
||||
when "bulk_coop_supplier_report"
|
||||
@supplier_report.header
|
||||
when "bulk_coop_allocation"
|
||||
@allocation_report.header
|
||||
when "bulk_coop_packing_sheets"
|
||||
[I18n.t(:report_header_customer),
|
||||
I18n.t(:report_header_product),
|
||||
I18n.t(:report_header_variant),
|
||||
I18n.t(:report_header_sum_total)]
|
||||
when "bulk_coop_customer_payments"
|
||||
[I18n.t(:report_header_customer),
|
||||
I18n.t(:report_header_date_of_order),
|
||||
I18n.t(:report_header_total_cost),
|
||||
I18n.t(:report_header_amount_owing),
|
||||
I18n.t(:report_header_amount_paid)]
|
||||
else
|
||||
[I18n.t(:report_header_supplier),
|
||||
I18n.t(:report_header_product),
|
||||
I18n.t(:report_header_product),
|
||||
I18n.t(:report_header_bulk_unit_size),
|
||||
I18n.t(:report_header_variant),
|
||||
I18n.t(:report_header_weight),
|
||||
I18n.t(:report_header_sum_total),
|
||||
I18n.t(:report_header_sum_max_total),
|
||||
I18n.t(:report_header_units_required),
|
||||
I18n.t(:report_header_remainder)]
|
||||
end
|
||||
end
|
||||
|
||||
def search
|
||||
report_line_items.orders
|
||||
end
|
||||
|
||||
def table_items
|
||||
return [] unless @render_table
|
||||
|
||||
report_line_items.list(line_item_includes)
|
||||
end
|
||||
|
||||
def rules
|
||||
case params[:report_type]
|
||||
when "bulk_coop_supplier_report"
|
||||
@supplier_report.rules
|
||||
when "bulk_coop_allocation"
|
||||
@allocation_report.rules
|
||||
when "bulk_coop_packing_sheets"
|
||||
[{ group_by: proc { |li| li.product },
|
||||
sort_by: proc { |product| product.name } },
|
||||
{ group_by: proc { |li| li.full_name },
|
||||
sort_by: proc { |full_name| full_name } },
|
||||
{ group_by: proc { |li| li.order },
|
||||
sort_by: proc { |order| order.to_s } }]
|
||||
when "bulk_coop_customer_payments"
|
||||
[{ group_by: proc { |li| li.order },
|
||||
sort_by: proc { |order| order.completed_at } }]
|
||||
else
|
||||
[{ group_by: proc { |li| li.product.supplier },
|
||||
sort_by: proc { |supplier| supplier.name } },
|
||||
{ group_by: proc { |li| li.product },
|
||||
sort_by: proc { |product| product.name },
|
||||
summary_columns: [proc { |lis| lis.first.product.supplier.name },
|
||||
proc { |lis| lis.first.product.name },
|
||||
proc { |lis| lis.first.product.group_buy_unit_size || 0.0 },
|
||||
proc { |_lis| "" },
|
||||
proc { |_lis| "" },
|
||||
proc { |lis|
|
||||
lis.sum { |li|
|
||||
li.quantity * (li.weight_from_unit_value || 0)
|
||||
}
|
||||
},
|
||||
proc { |lis|
|
||||
lis.sum { |li|
|
||||
(li.max_quantity || 0) * (li.weight_from_unit_value || 0)
|
||||
}
|
||||
},
|
||||
proc { |lis|
|
||||
( if (lis.first.product.group_buy_unit_size || 0).zero?
|
||||
0
|
||||
else
|
||||
( lis.sum { |li|
|
||||
[li.max_quantity || 0,
|
||||
li.quantity || 0].max * (li.weight_from_unit_value || 0)
|
||||
} / lis.first.product.group_buy_unit_size )
|
||||
end ).floor
|
||||
},
|
||||
proc { |lis|
|
||||
lis.sum { |li|
|
||||
[li.max_quantity || 0,
|
||||
li.quantity || 0].max * (li.weight_from_unit_value || 0)
|
||||
} - ( ( if (lis.first.product.group_buy_unit_size || 0).zero?
|
||||
0
|
||||
else
|
||||
( lis.sum { |li|
|
||||
[li.max_quantity || 0,
|
||||
li.quantity || 0].max * (li.weight_from_unit_value || 0)
|
||||
} / lis.first.product.group_buy_unit_size )
|
||||
end ).floor * (lis.first.product.group_buy_unit_size || 0) )
|
||||
}] },
|
||||
{ group_by: proc { |li| li.full_name },
|
||||
sort_by: proc { |full_name| full_name } }]
|
||||
end
|
||||
end
|
||||
|
||||
def columns
|
||||
case params[:report_type]
|
||||
when "bulk_coop_supplier_report"
|
||||
@supplier_report.columns
|
||||
when "bulk_coop_allocation"
|
||||
@allocation_report.columns
|
||||
when "bulk_coop_packing_sheets"
|
||||
[
|
||||
:order_billing_address_name,
|
||||
:product_name,
|
||||
:full_name,
|
||||
:total_quantity
|
||||
]
|
||||
when "bulk_coop_customer_payments"
|
||||
[
|
||||
:order_billing_address_name,
|
||||
:order_completed_at,
|
||||
:customer_payments_total_cost,
|
||||
:customer_payments_amount_owed,
|
||||
:customer_payments_amount_paid
|
||||
]
|
||||
else
|
||||
[
|
||||
:product_supplier_name,
|
||||
:product_name,
|
||||
:product_group_buy_unit_size,
|
||||
:full_name,
|
||||
:weight_from_unit_value,
|
||||
:total_quantity,
|
||||
:total_max_quantity,
|
||||
:empty_cell,
|
||||
:empty_cell
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :filter_canceled
|
||||
|
||||
def line_item_includes
|
||||
[
|
||||
{
|
||||
order: [:bill_address],
|
||||
variant: [{ option_values: :option_type }, { product: :supplier }]
|
||||
},
|
||||
:option_values
|
||||
]
|
||||
end
|
||||
|
||||
def order_permissions
|
||||
@order_permissions ||= ::Permissions::Order.new(@user, filter_canceled)
|
||||
end
|
||||
|
||||
def report_line_items
|
||||
@report_line_items ||= OpenFoodNetwork::Reports::LineItems.new(
|
||||
order_permissions,
|
||||
@params,
|
||||
CompleteVisibleOrders.new(order_permissions).query
|
||||
)
|
||||
end
|
||||
|
||||
def customer_payments_total_cost(line_items)
|
||||
unique_orders(line_items).sum(&:total)
|
||||
end
|
||||
|
||||
def customer_payments_amount_owed(line_items)
|
||||
unique_orders(line_items).sum(&:new_outstanding_balance)
|
||||
end
|
||||
|
||||
def customer_payments_amount_paid(line_items)
|
||||
unique_orders(line_items).sum(&:payment_total)
|
||||
end
|
||||
|
||||
def unique_orders(line_items)
|
||||
line_items.map(&:order).uniq
|
||||
end
|
||||
|
||||
def empty_cell(_line_items)
|
||||
""
|
||||
end
|
||||
|
||||
def full_name(line_items)
|
||||
line_items.first.full_name
|
||||
end
|
||||
|
||||
def group_buy_unit_size(line_items)
|
||||
(line_items.first.variant.product.group_buy_unit_size || 0.0) /
|
||||
(line_items.first.product.variant_unit_scale || 1)
|
||||
end
|
||||
|
||||
def max_quantity_excess(line_items)
|
||||
max_quantity_amount(line_items) - total_amount(line_items)
|
||||
end
|
||||
|
||||
def max_quantity_amount(line_items)
|
||||
line_items.sum do |line_item|
|
||||
max_quantity = [line_item.max_quantity || 0, line_item.quantity || 0].max
|
||||
max_quantity * scaled_unit_value(line_item.variant)
|
||||
end
|
||||
end
|
||||
|
||||
def option_value_value(line_items)
|
||||
VariantUnits::OptionValueNamer.new(line_items.first).value
|
||||
end
|
||||
|
||||
def option_value_unit(line_items)
|
||||
VariantUnits::OptionValueNamer.new(line_items.first).unit
|
||||
end
|
||||
|
||||
def order_billing_address_name(line_items)
|
||||
billing_address = line_items.first.order.bill_address
|
||||
billing_address.firstname + " " + billing_address.lastname
|
||||
end
|
||||
|
||||
def order_completed_at(line_items)
|
||||
line_items.first.order.completed_at.to_s
|
||||
end
|
||||
|
||||
def product_group_buy_unit_size(line_items)
|
||||
line_items.first.product.group_buy_unit_size || 0.0
|
||||
end
|
||||
|
||||
def product_name(line_items)
|
||||
line_items.first.product.name
|
||||
end
|
||||
|
||||
def product_supplier_name(line_items)
|
||||
line_items.first.product.supplier.name
|
||||
end
|
||||
|
||||
def remainder(line_items)
|
||||
remainder = total_available(line_items) - total_amount(line_items)
|
||||
remainder >= 0 ? remainder : ''
|
||||
end
|
||||
|
||||
def scaled_final_weight_volume(line_item)
|
||||
(line_item.final_weight_volume || 0) / (line_item.product.variant_unit_scale || 1)
|
||||
end
|
||||
|
||||
def scaled_unit_value(variant)
|
||||
(variant.unit_value || 0) / (variant.product.variant_unit_scale || 1)
|
||||
end
|
||||
|
||||
def total_amount(line_items)
|
||||
line_items.sum { |li| scaled_final_weight_volume(li) }
|
||||
end
|
||||
|
||||
def total_available(line_items)
|
||||
units_required(line_items) * group_buy_unit_size(line_items)
|
||||
end
|
||||
|
||||
def total_max_quantity(line_items)
|
||||
line_items.sum { |line_item| line_item.max_quantity || 0 }
|
||||
end
|
||||
|
||||
def total_quantity(line_items)
|
||||
line_items.sum(&:quantity)
|
||||
end
|
||||
|
||||
def total_label(_line_items)
|
||||
I18n.t('admin.reports.total')
|
||||
end
|
||||
|
||||
def units_required(line_items)
|
||||
if group_buy_unit_size(line_items).zero?
|
||||
0
|
||||
else
|
||||
( total_amount(line_items) / group_buy_unit_size(line_items) ).ceil
|
||||
end
|
||||
end
|
||||
|
||||
def variant_product_group_buy_unit_size_f(line_items)
|
||||
group_buy_unit_size(line_items)
|
||||
end
|
||||
|
||||
def variant_product_name(line_items)
|
||||
line_items.first.variant.product.name
|
||||
end
|
||||
|
||||
def variant_product_supplier_name(line_items)
|
||||
line_items.first.variant.product.supplier.name
|
||||
end
|
||||
|
||||
def weight_from_unit_value(line_items)
|
||||
line_items.first.weight_from_unit_value || 0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,65 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module OrderManagement
|
||||
module Reports
|
||||
module BulkCoop
|
||||
class BulkCoopSupplierReport
|
||||
def header
|
||||
[
|
||||
I18n.t(:report_header_supplier),
|
||||
I18n.t(:report_header_product),
|
||||
I18n.t(:report_header_bulk_unit_size),
|
||||
I18n.t(:report_header_variant),
|
||||
I18n.t(:report_header_variant_value),
|
||||
I18n.t(:report_header_variant_unit),
|
||||
I18n.t(:report_header_weight),
|
||||
I18n.t(:report_header_sum_total),
|
||||
I18n.t(:report_header_units_required),
|
||||
I18n.t(:report_header_unallocated),
|
||||
I18n.t(:report_header_max_quantity_excess),
|
||||
]
|
||||
end
|
||||
|
||||
def rules
|
||||
[
|
||||
{ group_by: proc { |line_item| line_item.product.supplier },
|
||||
sort_by: proc { |supplier| supplier.name } },
|
||||
{ group_by: proc { |line_item| line_item.product },
|
||||
sort_by: proc { |product| product.name },
|
||||
summary_columns: [
|
||||
:variant_product_supplier_name,
|
||||
:variant_product_name,
|
||||
:variant_product_group_buy_unit_size_f,
|
||||
:empty_cell,
|
||||
:empty_cell,
|
||||
:empty_cell,
|
||||
:empty_cell,
|
||||
:total_amount,
|
||||
:units_required,
|
||||
:remainder,
|
||||
:max_quantity_excess
|
||||
] },
|
||||
{ group_by: proc { |line_item| line_item.full_name },
|
||||
sort_by: proc { |full_name| full_name } }
|
||||
]
|
||||
end
|
||||
|
||||
def columns
|
||||
[
|
||||
:variant_product_supplier_name,
|
||||
:variant_product_name,
|
||||
:variant_product_group_buy_unit_size_f,
|
||||
:full_name,
|
||||
:option_value_value,
|
||||
:option_value_unit,
|
||||
:weight_from_unit_value,
|
||||
:total_amount,
|
||||
:empty_cell,
|
||||
:empty_cell,
|
||||
:empty_cell
|
||||
]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,45 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module OrderManagement
|
||||
module Reports
|
||||
module BulkCoop
|
||||
class Parameters < ::Reports::Parameters::Base
|
||||
extend ActiveModel::Naming
|
||||
extend ActiveModel::Translation
|
||||
include ActiveModel::Validations
|
||||
|
||||
attr_accessor :start_at, :end_at, :distributor_ids, :report_type
|
||||
|
||||
before_validation :cleanup_arrays
|
||||
|
||||
validates :start_at, :end_at, date_time_string: true
|
||||
validates :distributor_ids, integer_array: true
|
||||
validates_inclusion_of :report_type, in: BulkCoopReport::REPORT_TYPES.map(&:to_s)
|
||||
|
||||
validate :require_valid_datetime_range
|
||||
|
||||
def initialize(attributes = {})
|
||||
self.distributor_ids = []
|
||||
|
||||
super(attributes)
|
||||
end
|
||||
|
||||
def authorize!(permissions)
|
||||
authorizer = Authorizer.new(self, permissions)
|
||||
authorizer.authorize!
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# Remove the blank strings that Rails multiple selects add by default to
|
||||
# make sure that blank lists are still submitted to the server as arrays
|
||||
# instead of nil.
|
||||
#
|
||||
# https://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-select
|
||||
def cleanup_arrays
|
||||
distributor_ids.reject!(&:blank?)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,13 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module OrderManagement
|
||||
module Reports
|
||||
module BulkCoop
|
||||
class Permissions < ::Reports::Permissions
|
||||
def allowed_distributors
|
||||
@allowed_distributors ||= Enterprise.is_distributor.managed_by(user)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,32 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module OrderManagement
|
||||
module Reports
|
||||
module BulkCoop
|
||||
module Renderers
|
||||
class CsvRenderer < ::Reports::Renderers::Base
|
||||
def render(context)
|
||||
context.send_data(generate, filename: filename)
|
||||
end
|
||||
|
||||
def generate
|
||||
CSV.generate do |csv|
|
||||
csv << report_data.header
|
||||
|
||||
report_data.list.each do |data|
|
||||
csv << data
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def filename
|
||||
timestamp = Time.zone.now.strftime("%Y%m%d")
|
||||
"#{report_data.parameters[:report_type]}_#{timestamp}.csv"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,22 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module OrderManagement
|
||||
module Reports
|
||||
module BulkCoop
|
||||
module Renderers
|
||||
class HtmlRenderer < ::Reports::Renderers::Base
|
||||
def render(context)
|
||||
context.instance_variable_set :@renderer, self
|
||||
context.render(action: :create, renderer: self)
|
||||
end
|
||||
|
||||
delegate :header, to: :report_data
|
||||
|
||||
def data_rows
|
||||
report_data.list
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,29 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'open_food_network/order_grouper'
|
||||
|
||||
module OrderManagement
|
||||
module Reports
|
||||
module BulkCoop
|
||||
class ReportService
|
||||
attr_accessor :permissions, :parameters, :user
|
||||
|
||||
def initialize(permissions, parameters, user)
|
||||
@permissions = permissions
|
||||
@parameters = parameters
|
||||
@user = user
|
||||
@report = BulkCoopReport.new(user, parameters, true)
|
||||
end
|
||||
|
||||
def header
|
||||
@report.header
|
||||
end
|
||||
|
||||
def list
|
||||
order_grouper = OpenFoodNetwork::OrderGrouper.new @report.rules, @report.columns, @report
|
||||
order_grouper.table(@report.table_items)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,66 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module OrderManagement
|
||||
module Reports
|
||||
module EnterpriseFeeSummary
|
||||
module Renderers
|
||||
class CsvRenderer < ::Reports::Renderers::Base
|
||||
def render(context)
|
||||
context.send_data(generate, filename: filename)
|
||||
end
|
||||
|
||||
def generate
|
||||
CSV.generate do |csv|
|
||||
render_header(csv)
|
||||
|
||||
report_data.list.each do |data|
|
||||
render_data_row(csv, data)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def filename
|
||||
timestamp = Time.zone.now.strftime("%Y%m%d")
|
||||
"enterprise_fee_summary_#{timestamp}.csv"
|
||||
end
|
||||
|
||||
def render_header(csv)
|
||||
csv << [
|
||||
header_label(:fee_type),
|
||||
header_label(:enterprise_name),
|
||||
header_label(:fee_name),
|
||||
header_label(:customer_name),
|
||||
header_label(:fee_placement),
|
||||
header_label(:fee_calculated_on_transfer_through_name),
|
||||
header_label(:tax_category_name),
|
||||
header_label(:total_amount)
|
||||
]
|
||||
end
|
||||
|
||||
def render_data_row(csv, data)
|
||||
csv << [
|
||||
data.fee_type,
|
||||
data.enterprise_name,
|
||||
data.fee_name,
|
||||
data.customer_name,
|
||||
data.fee_placement,
|
||||
data.fee_calculated_on_transfer_through_name,
|
||||
data.tax_category_name,
|
||||
data.total_amount
|
||||
]
|
||||
end
|
||||
|
||||
def header_label(attribute)
|
||||
I18n.t("header.#{attribute}", scope: i18n_scope)
|
||||
end
|
||||
|
||||
def i18n_scope
|
||||
"order_management.reports.enterprise_fee_summary.formats.csv"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,53 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module OrderManagement
|
||||
module Reports
|
||||
module EnterpriseFeeSummary
|
||||
module Renderers
|
||||
class HtmlRenderer < ::Reports::Renderers::Base
|
||||
def render(context)
|
||||
context.instance_variable_set :@renderer, self
|
||||
context.render(action: :create, renderer: self)
|
||||
end
|
||||
|
||||
def header
|
||||
data_row_attributes.map do |attribute|
|
||||
header_label(attribute)
|
||||
end
|
||||
end
|
||||
|
||||
def data_rows
|
||||
report_data.list.map do |data|
|
||||
data_row_attributes.map do |attribute|
|
||||
data.public_send(attribute)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def data_row_attributes
|
||||
[
|
||||
:fee_type,
|
||||
:enterprise_name,
|
||||
:fee_name,
|
||||
:customer_name,
|
||||
:fee_placement,
|
||||
:fee_calculated_on_transfer_through_name,
|
||||
:tax_category_name,
|
||||
:total_amount
|
||||
]
|
||||
end
|
||||
|
||||
def header_label(attribute)
|
||||
I18n.t("header.#{attribute}", scope: i18n_scope)
|
||||
end
|
||||
|
||||
def i18n_scope
|
||||
"order_management.reports.enterprise_fee_summary.formats.csv"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,49 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module OrderManagement
|
||||
module Reports
|
||||
module EnterpriseFeeSummary
|
||||
class ReportService
|
||||
attr_accessor :permissions, :parameters
|
||||
|
||||
def initialize(permissions, parameters)
|
||||
@permissions = permissions
|
||||
@parameters = parameters
|
||||
end
|
||||
|
||||
def enterprise_fees_by_customer
|
||||
Scope.new.apply_filters(permission_filters).apply_filters(parameters).result
|
||||
end
|
||||
|
||||
def list
|
||||
enterprise_fee_type_total_list.sort
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def permission_filters
|
||||
Parameters.new(order_cycle_ids: permissions.allowed_order_cycles.map(&:id))
|
||||
end
|
||||
|
||||
def enterprise_fee_type_total_list
|
||||
enterprise_fees_by_customer.map do |total_data|
|
||||
summarizer = Summarizer.new(total_data)
|
||||
|
||||
ReportData::EnterpriseFeeTypeTotal.new.tap do |total|
|
||||
enterprise_fee_type_summarizer_to_total_attributes.each do |attribute|
|
||||
total.public_send("#{attribute}=", summarizer.public_send(attribute))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def enterprise_fee_type_summarizer_to_total_attributes
|
||||
[
|
||||
:fee_type, :enterprise_name, :fee_name, :customer_name, :fee_placement,
|
||||
:fee_calculated_on_transfer_through_name, :tax_category_name, :total_amount
|
||||
]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,5 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Reports
|
||||
class UnsupportedReportFormatException < StandardError; end
|
||||
end
|
||||
@@ -1,29 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Reports
|
||||
class Authorizer
|
||||
class ParameterNotAllowedError < StandardError; end
|
||||
|
||||
attr_accessor :parameters, :permissions
|
||||
|
||||
def initialize(parameters, permissions)
|
||||
@parameters = parameters
|
||||
@permissions = permissions
|
||||
end
|
||||
|
||||
def self.parameter_not_allowed_error_message
|
||||
i18n_scope = "order_management.reports.enterprise_fee_summary"
|
||||
I18n.t("parameter_not_allowed_error", scope: i18n_scope)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def require_ids_allowed(array, allowed_objects)
|
||||
error_klass = ::Reports::Authorizer::ParameterNotAllowedError
|
||||
error_message = self.class.parameter_not_allowed_error_message
|
||||
ids_allowed = (array - allowed_objects.map(&:id).map(&:to_s)).blank?
|
||||
|
||||
raise error_klass, error_message unless ids_allowed
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,35 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Reports
|
||||
module Parameters
|
||||
class Base
|
||||
extend ActiveModel::Naming
|
||||
extend ActiveModel::Translation
|
||||
include ActiveModel::Validations
|
||||
include ActiveModel::Validations::Callbacks
|
||||
|
||||
def initialize(attributes = {})
|
||||
attributes.each do |key, value|
|
||||
public_send("#{key}=", value)
|
||||
end
|
||||
end
|
||||
|
||||
def self.date_end_before_start_error_message
|
||||
i18n_scope = "order_management.reports.enterprise_fee_summary"
|
||||
I18n.t("date_end_before_start_error", scope: i18n_scope)
|
||||
end
|
||||
|
||||
# The parameters are never persisted.
|
||||
def to_key; end
|
||||
|
||||
protected
|
||||
|
||||
def require_valid_datetime_range
|
||||
return if start_at.blank? || end_at.blank?
|
||||
|
||||
error_message = self.class.date_end_before_start_error_message
|
||||
errors.add(:end_at, error_message) unless start_at < end_at
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,11 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Reports
|
||||
class Permissions
|
||||
attr_accessor :user
|
||||
|
||||
def initialize(user)
|
||||
@user = user
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,13 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Reports
|
||||
module Renderers
|
||||
class Base
|
||||
attr_reader :report_data
|
||||
|
||||
def initialize(report_data)
|
||||
@report_data = report_data
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,13 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Reports
|
||||
module ReportData
|
||||
class Base
|
||||
def initialize(attributes = {})
|
||||
attributes.each do |key, value|
|
||||
public_send("#{key}=", value)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,19 +0,0 @@
|
||||
- if @report.present?
|
||||
%table#enterprise_fee_summary_report.report__table
|
||||
%thead
|
||||
%tr
|
||||
- @renderer.header.each do |heading|
|
||||
%th= heading
|
||||
|
||||
%tbody
|
||||
- @renderer.data_rows.each do |row|
|
||||
%tr
|
||||
- row.each do |cell_value|
|
||||
%td= cell_value
|
||||
|
||||
- if @renderer.data_rows.empty?
|
||||
%tr
|
||||
%td{colspan: @renderer.header.length}= t('.none')
|
||||
- else
|
||||
%p.report__message
|
||||
= t(".select_and_search")
|
||||
@@ -1,34 +0,0 @@
|
||||
= form_for @report_parameters, as: :report, url: main_app.order_management_reports_bulk_coop_path, method: :post do |f|
|
||||
.row.date-range-filter
|
||||
.sixteen.columns.alpha
|
||||
= label_tag nil, t(".date_range")
|
||||
%br
|
||||
|
||||
= f.label :start_at, class: "inline"
|
||||
= f.text_field :start_at, class: "datetimepicker datepicker-from"
|
||||
|
||||
%span.range-divider
|
||||
%i.icon-arrow-right
|
||||
|
||||
= f.text_field :end_at, class: "datetimepicker datepicker-to"
|
||||
= f.label :end_at, class: "inline"
|
||||
|
||||
.row
|
||||
.sixteen.columns.alpha
|
||||
= f.label :distributor_ids
|
||||
= f.collection_select(:distributor_ids, @permissions.allowed_distributors, :id, :name, {}, {class: "select2 fullwidth", multiple: true})
|
||||
|
||||
.row
|
||||
.sixteen.columns.alpha
|
||||
= f.label :report_type
|
||||
= f.collection_select(:report_type, OrderManagement::Reports::BulkCoop::BulkCoopReport::REPORT_TYPES.map { |report_type| [t(".#{report_type}"), report_type] }, :last, :first, {}, {class: "select2 fullwidth", multiple: false})
|
||||
|
||||
.row
|
||||
.sixteen.columns.alpha
|
||||
= check_box_tag :report_format, "csv", false, id: "report_format_csv"
|
||||
= label_tag :report_format_csv, t(".report_format_csv")
|
||||
|
||||
= button t(".generate_report")
|
||||
|
||||
= render partial: "spree/admin/reports/customer_names_message"
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
- if @report.present?
|
||||
%table#bulk_coop_report.report__table
|
||||
%thead
|
||||
%tr
|
||||
- @renderer.header.each do |heading|
|
||||
%th= heading
|
||||
|
||||
%tbody
|
||||
- @renderer.data_rows.each do |row|
|
||||
%tr
|
||||
- row.each do |cell_value|
|
||||
%td= cell_value
|
||||
|
||||
- if @renderer.data_rows.empty?
|
||||
%tr
|
||||
%td{colspan: @renderer.header.length}= t('.none')
|
||||
- else
|
||||
%p.report__message
|
||||
= t(".select_and_search")
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
= render "filters"
|
||||
= render "order_management/reports/report"
|
||||
@@ -1 +0,0 @@
|
||||
= render "filters"
|
||||
@@ -1,52 +0,0 @@
|
||||
= form_for @report_parameters, as: :report, url: main_app.order_management_reports_enterprise_fee_summary_path, method: :post do |f|
|
||||
.row.date-range-filter
|
||||
.sixteen.columns.alpha
|
||||
= label_tag nil, t(".date_range")
|
||||
%br
|
||||
|
||||
= f.label :start_at, class: "inline"
|
||||
= f.text_field :start_at, class: "datetimepicker datepicker-from"
|
||||
|
||||
%span.range-divider
|
||||
%i.icon-arrow-right
|
||||
|
||||
= f.text_field :end_at, class: "datetimepicker datepicker-to"
|
||||
= f.label :end_at, class: "inline"
|
||||
|
||||
.row
|
||||
.sixteen.columns.alpha
|
||||
= f.label :distributor_ids
|
||||
= f.collection_select(:distributor_ids, @permissions.allowed_distributors, :id, :name, {}, {class: "select2 fullwidth", multiple: true})
|
||||
|
||||
.row
|
||||
.sixteen.columns.alpha
|
||||
= f.label :producer_ids
|
||||
= f.collection_select(:producer_ids, @permissions.allowed_producers, :id, :name, {}, {class: "select2 fullwidth", multiple: true})
|
||||
|
||||
.row
|
||||
.sixteen.columns.alpha
|
||||
= f.label :order_cycle_ids
|
||||
= f.collection_select(:order_cycle_ids, @permissions.allowed_order_cycles, :id, :name, {}, {class: "select2 fullwidth", multiple: true})
|
||||
|
||||
.row
|
||||
.eight.columns.alpha
|
||||
= f.label :enterprise_fee_ids
|
||||
= f.collection_select(:enterprise_fee_ids, @permissions.allowed_enterprise_fees, :id, :name, {}, {class: "select2 fullwidth", multiple: true})
|
||||
.eight.columns.omega
|
||||
= f.label :shipping_method_ids
|
||||
= f.collection_select(:shipping_method_ids, @permissions.allowed_shipping_methods, :id, :name, {}, {class: "select2 fullwidth", multiple: true})
|
||||
|
||||
.row
|
||||
.eight.columns.alpha
|
||||
.eight.columns.omega
|
||||
= f.label :payment_method_ids
|
||||
= f.collection_select(:payment_method_ids, @permissions.allowed_payment_methods, :id, :name, {}, {class: "select2 fullwidth", multiple: true})
|
||||
|
||||
.row
|
||||
.sixteen.columns.alpha
|
||||
= check_box_tag :report_format, "csv", false, id: "report_format_csv"
|
||||
= label_tag :report_format_csv, t(".report_format_csv")
|
||||
|
||||
= button t(".generate_report")
|
||||
|
||||
= render partial: "spree/admin/reports/customer_names_message"
|
||||
@@ -1,2 +0,0 @@
|
||||
= render "filters"
|
||||
= render "order_management/reports/report"
|
||||
@@ -1 +0,0 @@
|
||||
= render "filters"
|
||||
@@ -1,103 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "spec_helper"
|
||||
|
||||
describe OrderManagement::Reports::BulkCoopController, type: :controller do
|
||||
let(:report_klass) { OrderManagement::Reports::BulkCoop }
|
||||
|
||||
let!(:distributor) { create(:distributor_enterprise) }
|
||||
|
||||
let(:current_user) { distributor.owner }
|
||||
|
||||
before do
|
||||
allow(controller).to receive(:spree_current_user) { current_user }
|
||||
end
|
||||
|
||||
describe "#new" do
|
||||
it "renders the report form" do
|
||||
get :new
|
||||
|
||||
expect(response.status).to eq 200
|
||||
expect(response).to render_template(new_template_path)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#create" do
|
||||
context "when the parameters are valid" do
|
||||
it "sends the generated report in the correct format" do
|
||||
post :create, params: {
|
||||
report: {
|
||||
start_at: "2018-10-09 07:30:00",
|
||||
report_type: "bulk_coop_supplier_report"
|
||||
}, report_format: "csv"
|
||||
}
|
||||
|
||||
expect(response.status).to eq 200
|
||||
expect(response.body).not_to be_blank
|
||||
expect(response.header["Content-Type"]).to eq("text/csv")
|
||||
end
|
||||
end
|
||||
|
||||
context "when the parameters are invalid" do
|
||||
it "renders the report form with an error" do
|
||||
post :create, params: {
|
||||
report: {
|
||||
start_at: "invalid_date",
|
||||
report_type: "bulk_coop_supplier_report"
|
||||
}, report_format: "csv"
|
||||
}
|
||||
|
||||
expect(flash[:error]).to eq(I18n.t("invalid_filter_parameters", scope: i18n_scope))
|
||||
expect(response).to render_template(new_template_path)
|
||||
end
|
||||
end
|
||||
|
||||
context "when some parameters are now allowed" do
|
||||
let!(:distributor) { create(:distributor_enterprise) }
|
||||
let!(:other_distributor) { create(:distributor_enterprise) }
|
||||
|
||||
let(:current_user) { distributor.owner }
|
||||
|
||||
it "renders the report form with an error" do
|
||||
post :create, params: {
|
||||
report: {
|
||||
distributor_ids: [other_distributor.id],
|
||||
report_type: "bulk_coop_supplier_report"
|
||||
}, report_format: "csv"
|
||||
}
|
||||
|
||||
expect(flash[:error]).to eq(report_klass::Authorizer.parameter_not_allowed_error_message)
|
||||
expect(response).to render_template(new_template_path)
|
||||
end
|
||||
end
|
||||
|
||||
describe "filtering results based on permissions" do
|
||||
let!(:distributor) { create(:distributor_enterprise) }
|
||||
let!(:other_distributor) { create(:distributor_enterprise) }
|
||||
|
||||
let(:current_user) { distributor.owner }
|
||||
|
||||
it "applies permissions to report" do
|
||||
post :create, params: { report: {}, report_format: "csv" }
|
||||
|
||||
expect(assigns(:permissions).allowed_distributors.to_a).to eq([distributor])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def default_report_params
|
||||
{
|
||||
report_type: "bulk_coop_supplier_report"
|
||||
}
|
||||
end
|
||||
|
||||
def i18n_scope
|
||||
"order_management.reports.enterprise_fee_summary"
|
||||
end
|
||||
|
||||
def new_template_path
|
||||
"order_management/reports/bulk_coop/new"
|
||||
end
|
||||
end
|
||||
@@ -1,89 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "spec_helper"
|
||||
|
||||
describe OrderManagement::Reports::EnterpriseFeeSummariesController, type: :controller do
|
||||
let(:report_klass) { OrderManagement::Reports::EnterpriseFeeSummary }
|
||||
|
||||
let!(:distributor) { create(:distributor_enterprise) }
|
||||
|
||||
let(:current_user) { distributor.owner }
|
||||
|
||||
before do
|
||||
allow(controller).to receive(:spree_current_user) { current_user }
|
||||
end
|
||||
|
||||
describe "#new" do
|
||||
it "renders the report form" do
|
||||
get :new
|
||||
|
||||
expect(response.status).to eq 200
|
||||
expect(response).to render_template(new_template_path)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#create" do
|
||||
context "when the parameters are valid" do
|
||||
it "sends the generated report in the correct format" do
|
||||
post :create, params: {
|
||||
report: { start_at: "2018-10-09 07:30:00" }, report_format: "csv"
|
||||
}
|
||||
|
||||
expect(response.status).to eq 200
|
||||
expect(response.body).not_to be_blank
|
||||
expect(response.header["Content-Type"]).to eq("text/csv")
|
||||
end
|
||||
end
|
||||
|
||||
context "when the parameters are invalid" do
|
||||
it "renders the report form with an error" do
|
||||
post :create, params: {
|
||||
report: { start_at: "invalid date" }, report_format: "csv"
|
||||
}
|
||||
|
||||
expect(flash[:error]).to eq(I18n.t("invalid_filter_parameters", scope: i18n_scope))
|
||||
expect(response).to render_template(new_template_path)
|
||||
end
|
||||
end
|
||||
|
||||
context "when some parameters are now allowed" do
|
||||
let!(:distributor) { create(:distributor_enterprise) }
|
||||
let!(:other_distributor) { create(:distributor_enterprise) }
|
||||
|
||||
let(:current_user) { distributor.owner }
|
||||
|
||||
it "renders the report form with an error" do
|
||||
post :create, params: {
|
||||
report: { distributor_ids: [other_distributor.id] }, report_format: "csv"
|
||||
}
|
||||
|
||||
expect(flash[:error]).to eq(report_klass::Authorizer.parameter_not_allowed_error_message)
|
||||
expect(response).to render_template(new_template_path)
|
||||
end
|
||||
end
|
||||
|
||||
describe "filtering results based on permissions" do
|
||||
let!(:distributor) { create(:distributor_enterprise) }
|
||||
let!(:other_distributor) { create(:distributor_enterprise) }
|
||||
|
||||
let!(:order_cycle) { create(:simple_order_cycle, coordinator: distributor) }
|
||||
let!(:other_order_cycle) { create(:simple_order_cycle, coordinator: other_distributor) }
|
||||
|
||||
let(:current_user) { distributor.owner }
|
||||
|
||||
it "applies permissions to report" do
|
||||
post :create, params: { report: {}, report_format: "csv" }
|
||||
|
||||
expect(assigns(:permissions).allowed_order_cycles.to_a).to eq([order_cycle])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def i18n_scope
|
||||
"order_management.reports.enterprise_fee_summary"
|
||||
end
|
||||
|
||||
def new_template_path
|
||||
"order_management/reports/enterprise_fee_summaries/new"
|
||||
end
|
||||
end
|
||||
@@ -1,75 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "spec_helper"
|
||||
|
||||
feature "bulk coop" do
|
||||
include AuthenticationHelper
|
||||
include WebHelper
|
||||
|
||||
scenario "generating Bulk Co-op Supplier Report" do
|
||||
login_as_admin_and_visit new_order_management_reports_bulk_coop_path
|
||||
select "Bulk Co-op Supplier Report", from: "report_report_type"
|
||||
click_button 'Generate Report'
|
||||
|
||||
expect(page).to have_table_row [
|
||||
"Supplier",
|
||||
"Product",
|
||||
"Bulk Unit Size",
|
||||
"Variant",
|
||||
"Variant Value",
|
||||
"Variant Unit",
|
||||
"Weight",
|
||||
"Sum Total",
|
||||
"Units Required",
|
||||
"Unallocated",
|
||||
"Max Quantity Excess"
|
||||
]
|
||||
end
|
||||
|
||||
scenario "generating Bulk Co-op Allocation report" do
|
||||
login_as_admin_and_visit new_order_management_reports_bulk_coop_path
|
||||
select "Bulk Co-op Allocation", from: "report_report_type"
|
||||
click_button 'Generate Report'
|
||||
|
||||
expect(page).to have_table_row [
|
||||
"Customer",
|
||||
"Product",
|
||||
"Bulk Unit Size",
|
||||
"Variant",
|
||||
"Variant Value",
|
||||
"Variant Unit",
|
||||
"Weight",
|
||||
"Sum Total",
|
||||
"Total available",
|
||||
"Unallocated",
|
||||
"Max Quantity Excess"
|
||||
]
|
||||
end
|
||||
|
||||
scenario "generating Bulk Co-op Packing Sheets report" do
|
||||
login_as_admin_and_visit new_order_management_reports_bulk_coop_path
|
||||
select "Bulk Co-op Packing Sheets", from: "report_report_type"
|
||||
click_button 'Generate Report'
|
||||
|
||||
expect(page).to have_table_row [
|
||||
"Customer",
|
||||
"Product",
|
||||
"Variant",
|
||||
"Sum Total"
|
||||
]
|
||||
end
|
||||
|
||||
scenario "generating Bulk Co-op Customer Payments report" do
|
||||
login_as_admin_and_visit new_order_management_reports_bulk_coop_path
|
||||
select "Bulk Co-op Customer Payments", from: "report_report_type"
|
||||
click_button 'Generate Report'
|
||||
|
||||
expect(page).to have_table_row [
|
||||
"Customer",
|
||||
"Date of Order",
|
||||
"Total Cost",
|
||||
"Amount Owing",
|
||||
"Amount Paid"
|
||||
]
|
||||
end
|
||||
end
|
||||
@@ -1,186 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe OrderManagement::Reports::BulkCoop::BulkCoopReport do
|
||||
subject { OrderManagement::Reports::BulkCoop::BulkCoopReport.new user, params, true }
|
||||
let(:user) { create(:admin_user) }
|
||||
|
||||
describe '#table_items' do
|
||||
let(:params) { {} }
|
||||
|
||||
let(:d1) { create(:distributor_enterprise) }
|
||||
let(:oc1) { create(:simple_order_cycle) }
|
||||
let(:o1) { create(:order, completed_at: 1.day.ago, order_cycle: oc1, distributor: d1) }
|
||||
let(:li1) { build(:line_item_with_shipment) }
|
||||
|
||||
before { o1.line_items << li1 }
|
||||
|
||||
context "as a site admin" do
|
||||
context 'when searching' do
|
||||
let(:params) { { q: { completed_at_gt: '', completed_at_lt: '', distributor_id_in: [] } } }
|
||||
|
||||
it "fetches completed orders" do
|
||||
o2 = create(:order, state: 'cart')
|
||||
o2.line_items << build(:line_item)
|
||||
expect(subject.table_items).to eq([li1])
|
||||
end
|
||||
|
||||
it 'shows canceled orders' do
|
||||
o2 = create(:order, state: 'canceled', completed_at: 1.day.ago, order_cycle: oc1,
|
||||
distributor: d1)
|
||||
line_item = build(:line_item_with_shipment)
|
||||
o2.line_items << line_item
|
||||
expect(subject.table_items).to include(line_item)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when not searching' do
|
||||
let(:params) { {} }
|
||||
|
||||
it "fetches completed orders" do
|
||||
o2 = create(:order, state: 'cart')
|
||||
o2.line_items << build(:line_item)
|
||||
expect(subject.table_items).to eq([li1])
|
||||
end
|
||||
|
||||
it 'shows canceled orders' do
|
||||
o2 = create(:order, state: 'canceled', completed_at: 1.day.ago, order_cycle: oc1,
|
||||
distributor: d1)
|
||||
line_item = build(:line_item_with_shipment)
|
||||
o2.line_items << line_item
|
||||
expect(subject.table_items).to include(line_item)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "filtering by date" do
|
||||
it do
|
||||
user = create(:admin_user)
|
||||
o2 = create(:order, completed_at: 3.days.ago, order_cycle: oc1, distributor: d1)
|
||||
li2 = build(:line_item_with_shipment)
|
||||
o2.line_items << li2
|
||||
|
||||
report = OrderManagement::Reports::BulkCoop::BulkCoopReport.new user, {}, true
|
||||
expect(report.table_items).to match_array [li1, li2]
|
||||
|
||||
report = OrderManagement::Reports::BulkCoop::BulkCoopReport.new(
|
||||
user, { q: { completed_at_gt: 2.days.ago } }, true
|
||||
)
|
||||
expect(report.table_items).to eq([li1])
|
||||
|
||||
report = OrderManagement::Reports::BulkCoop::BulkCoopReport.new(
|
||||
user, { q: { completed_at_lt: 2.days.ago } }, true
|
||||
)
|
||||
expect(report.table_items).to eq([li2])
|
||||
end
|
||||
end
|
||||
|
||||
context "filtering by distributor" do
|
||||
it do
|
||||
user = create(:admin_user)
|
||||
d2 = create(:distributor_enterprise)
|
||||
o2 = create(:order, distributor: d2, order_cycle: oc1,
|
||||
completed_at: Time.zone.now)
|
||||
li2 = build(:line_item_with_shipment)
|
||||
o2.line_items << li2
|
||||
|
||||
report = OrderManagement::Reports::BulkCoop::BulkCoopReport.new user, {}, true
|
||||
expect(report.table_items).to match_array [li1, li2]
|
||||
|
||||
report = OrderManagement::Reports::BulkCoop::BulkCoopReport.new(
|
||||
user, { q: { distributor_id_in: [d1.id] } }, true
|
||||
)
|
||||
expect(report.table_items).to eq([li1])
|
||||
|
||||
report = OrderManagement::Reports::BulkCoop::BulkCoopReport.new(
|
||||
user, { q: { distributor_id_in: [d2.id] } }, true
|
||||
)
|
||||
expect(report.table_items).to eq([li2])
|
||||
end
|
||||
end
|
||||
|
||||
context "as a manager of a supplier" do
|
||||
let!(:user) { create(:user) }
|
||||
subject { OrderManagement::Reports::BulkCoop::BulkCoopReport.new user, {}, true }
|
||||
|
||||
let(:s1) { create(:supplier_enterprise) }
|
||||
|
||||
before do
|
||||
s1.enterprise_roles.create!(user: user)
|
||||
end
|
||||
|
||||
context "that has granted P-OC to the distributor" do
|
||||
let(:o2) do
|
||||
create(:order, distributor: d1, completed_at: 1.day.ago, bill_address: create(:address),
|
||||
ship_address: create(:address))
|
||||
end
|
||||
let(:li2) do
|
||||
build(:line_item_with_shipment, product: create(:simple_product, supplier: s1))
|
||||
end
|
||||
|
||||
before do
|
||||
o2.line_items << li2
|
||||
create(:enterprise_relationship, parent: s1, child: d1,
|
||||
permissions_list: [:add_to_order_cycle])
|
||||
end
|
||||
|
||||
it "shows line items supplied by my producers, with names hidden" do
|
||||
expect(subject.table_items).to eq([li2])
|
||||
expect(subject.table_items.first.order.bill_address.firstname).to eq("HIDDEN")
|
||||
end
|
||||
end
|
||||
|
||||
context "that has not granted P-OC to the distributor" do
|
||||
let(:o2) do
|
||||
create(:order, distributor: d1, completed_at: 1.day.ago, bill_address: create(:address),
|
||||
ship_address: create(:address))
|
||||
end
|
||||
let(:li2) do
|
||||
build(:line_item_with_shipment, product: create(:simple_product, supplier: s1))
|
||||
end
|
||||
|
||||
before do
|
||||
o2.line_items << li2
|
||||
end
|
||||
|
||||
it "does not show line items supplied by my producers" do
|
||||
expect(subject.table_items).to eq([])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#columns' do
|
||||
context 'when report type is bulk_coop_customer_payments' do
|
||||
let(:params) { { report_type: 'bulk_coop_customer_payments' } }
|
||||
|
||||
it 'returns' do
|
||||
expect(subject.columns).to eq(
|
||||
[
|
||||
:order_billing_address_name,
|
||||
:order_completed_at,
|
||||
:customer_payments_total_cost,
|
||||
:customer_payments_amount_owed,
|
||||
:customer_payments_amount_paid,
|
||||
]
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Yes, I know testing a private method is bad practice but report's design, tighly coupling
|
||||
# OpenFoodNetwork::OrderGrouper and OrderManagement::Reports::BulkCoop::BulkCoopReport, makes it
|
||||
# very hard to make things testeable without ending up in a wormwhole. This is a trade-off.
|
||||
describe '#customer_payments_amount_owed' do
|
||||
let(:params) { {} }
|
||||
let(:user) { build(:user) }
|
||||
let!(:line_item) { create(:line_item) }
|
||||
let(:order) { line_item.order }
|
||||
|
||||
it 'calls #new_outstanding_balance' do
|
||||
expect_any_instance_of(Spree::Order).to receive(:new_outstanding_balance)
|
||||
subject.send(:customer_payments_amount_owed, [line_item])
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,174 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "spec_helper"
|
||||
|
||||
describe OrderManagement::Reports::EnterpriseFeeSummary::Authorizer do
|
||||
let(:report_klass) { OrderManagement::Reports::EnterpriseFeeSummary }
|
||||
let(:user) { create(:user) }
|
||||
|
||||
let(:parameters) { report_klass::Parameters.new(params) }
|
||||
let(:permissions) { report_klass::Permissions.new(user) }
|
||||
let(:authorizer) { described_class.new(parameters, permissions) }
|
||||
|
||||
context "for distributors" do
|
||||
before do
|
||||
allow(permissions).to receive(:allowed_distributors) do
|
||||
stub_model_collection(Enterprise, :id, ["1", "2", "3"])
|
||||
end
|
||||
end
|
||||
|
||||
context "when distributors are allowed" do
|
||||
let(:params) { { distributor_ids: ["1", "3"] } }
|
||||
|
||||
it "does not raise error" do
|
||||
expect { authorizer.authorize! }.not_to raise_error
|
||||
end
|
||||
end
|
||||
|
||||
context "when a distributor is not allowed" do
|
||||
let(:params) { { distributor_ids: ["1", "4"] } }
|
||||
|
||||
it "raises ParameterNotAllowedError" do
|
||||
expect { authorizer.authorize! }
|
||||
.to raise_error(Reports::Authorizer::ParameterNotAllowedError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "for producers" do
|
||||
before do
|
||||
allow(permissions).to receive(:allowed_producers) do
|
||||
stub_model_collection(Enterprise, :id, ["1", "2", "3"])
|
||||
end
|
||||
end
|
||||
|
||||
context "when producers are allowed" do
|
||||
let(:params) { { producer_ids: ["1", "3"] } }
|
||||
|
||||
it "does not raise error" do
|
||||
expect { authorizer.authorize! }.not_to raise_error
|
||||
end
|
||||
end
|
||||
|
||||
context "when a producer is not allowed" do
|
||||
let(:params) { { producer_ids: ["1", "4"] } }
|
||||
|
||||
it "raises ParameterNotAllowedError" do
|
||||
expect { authorizer.authorize! }
|
||||
.to raise_error(Reports::Authorizer::ParameterNotAllowedError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "for order cycles" do
|
||||
before do
|
||||
allow(permissions).to receive(:allowed_order_cycles) do
|
||||
stub_model_collection(OrderCycle, :id, ["1", "2", "3"])
|
||||
end
|
||||
end
|
||||
|
||||
context "when order cycles are allowed" do
|
||||
let(:params) { { order_cycle_ids: ["1", "3"] } }
|
||||
|
||||
it "does not raise error" do
|
||||
expect { authorizer.authorize! }.not_to raise_error
|
||||
end
|
||||
end
|
||||
|
||||
context "when an order cycle is not allowed" do
|
||||
let(:params) { { order_cycle_ids: ["1", "4"] } }
|
||||
|
||||
it "raises ParameterNotAllowedError" do
|
||||
expect { authorizer.authorize! }
|
||||
.to raise_error(Reports::Authorizer::ParameterNotAllowedError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "for enterprise fees" do
|
||||
before do
|
||||
allow(permissions).to receive(:allowed_enterprise_fees) do
|
||||
stub_model_collection(EnterpriseFee, :id, ["1", "2", "3"])
|
||||
end
|
||||
end
|
||||
|
||||
context "when enterprise fees are allowed" do
|
||||
let(:params) { { enterprise_fee_ids: ["1", "3"] } }
|
||||
|
||||
it "does not raise error" do
|
||||
expect { authorizer.authorize! }.not_to raise_error
|
||||
end
|
||||
end
|
||||
|
||||
context "when an enterprise fee is not allowed" do
|
||||
let(:params) { { enterprise_fee_ids: ["1", "4"] } }
|
||||
|
||||
it "raises ParameterNotAllowedError" do
|
||||
expect { authorizer.authorize! }
|
||||
.to raise_error(Reports::Authorizer::ParameterNotAllowedError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "for shipping methods" do
|
||||
before do
|
||||
allow(permissions).to receive(:allowed_shipping_methods) do
|
||||
stub_model_collection(Spree::ShippingMethod, :id, ["1", "2", "3"])
|
||||
end
|
||||
end
|
||||
|
||||
context "when shipping methods are allowed" do
|
||||
let(:params) { { shipping_method_ids: ["1", "3"] } }
|
||||
|
||||
it "does not raise error" do
|
||||
expect { authorizer.authorize! }.not_to raise_error
|
||||
end
|
||||
end
|
||||
|
||||
context "when a shipping method is not allowed" do
|
||||
let(:params) { { shipping_method_ids: ["1", "4"] } }
|
||||
|
||||
it "raises ParameterNotAllowedError" do
|
||||
expect { authorizer.authorize! }
|
||||
.to raise_error(Reports::Authorizer::ParameterNotAllowedError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "for payment methods" do
|
||||
before do
|
||||
allow(permissions).to receive(:allowed_payment_methods) do
|
||||
stub_model_collection(Spree::PaymentMethod, :id, ["1", "2", "3"])
|
||||
end
|
||||
end
|
||||
|
||||
context "when payment methods are allowed" do
|
||||
let(:params) { { payment_method_ids: ["1", "3"] } }
|
||||
|
||||
it "does not raise error" do
|
||||
expect { authorizer.authorize! }.not_to raise_error
|
||||
end
|
||||
end
|
||||
|
||||
context "when a payment method is not allowed" do
|
||||
let(:params) { { payment_method_ids: ["1", "4"] } }
|
||||
|
||||
it "raises ParameterNotAllowedError" do
|
||||
expect { authorizer.authorize! }
|
||||
.to raise_error(Reports::Authorizer::ParameterNotAllowedError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def stub_model_collection(model, attribute_name, attribute_list)
|
||||
attribute_list.map do |attribute_value|
|
||||
stub_model(model, attribute_name => attribute_value)
|
||||
end
|
||||
end
|
||||
|
||||
def stub_model(model, params)
|
||||
model.new.tap do |instance|
|
||||
instance.stub(params)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,90 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "spec_helper"
|
||||
|
||||
require "date_time_string_validator"
|
||||
|
||||
describe OrderManagement::Reports::EnterpriseFeeSummary::Parameters do
|
||||
describe "validation" do
|
||||
let(:parameters) { described_class.new }
|
||||
|
||||
it "allows all parameters to be blank" do
|
||||
expect(parameters).to be_valid
|
||||
end
|
||||
|
||||
context "for type of parameters" do
|
||||
it { is_expected.to validate_date_time_format_of(:start_at) }
|
||||
it { is_expected.to validate_date_time_format_of(:end_at) }
|
||||
it { is_expected.to validate_integer_array(:distributor_ids) }
|
||||
it { is_expected.to validate_integer_array(:producer_ids) }
|
||||
it { is_expected.to validate_integer_array(:order_cycle_ids) }
|
||||
it { is_expected.to validate_integer_array(:enterprise_fee_ids) }
|
||||
it { is_expected.to validate_integer_array(:shipping_method_ids) }
|
||||
it { is_expected.to validate_integer_array(:payment_method_ids) }
|
||||
|
||||
it "allows integer arrays to include blank string and cleans it up" do
|
||||
subject.distributor_ids = ["", "1"]
|
||||
subject.producer_ids = ["", "1"]
|
||||
subject.order_cycle_ids = ["", "1"]
|
||||
subject.enterprise_fee_ids = ["", "1"]
|
||||
subject.shipping_method_ids = ["", "1"]
|
||||
subject.payment_method_ids = ["", "1"]
|
||||
|
||||
expect(subject).to be_valid
|
||||
|
||||
expect(subject.distributor_ids).to eq(["1"])
|
||||
expect(subject.producer_ids).to eq(["1"])
|
||||
expect(subject.order_cycle_ids).to eq(["1"])
|
||||
expect(subject.enterprise_fee_ids).to eq(["1"])
|
||||
expect(subject.shipping_method_ids).to eq(["1"])
|
||||
expect(subject.payment_method_ids).to eq(["1"])
|
||||
end
|
||||
|
||||
describe "requiring start_at to be before end_at" do
|
||||
let(:now) { Time.zone.now.utc }
|
||||
|
||||
it "adds error when start_at is after end_at" do
|
||||
allow(subject).to receive(:start_at) { now.to_s }
|
||||
allow(subject).to receive(:end_at) { (now - 1.hour).to_s }
|
||||
|
||||
expect(subject).not_to be_valid
|
||||
error_message = described_class.date_end_before_start_error_message
|
||||
expect(subject.errors[:end_at]).to eq([error_message])
|
||||
end
|
||||
|
||||
it "does not add error when start_at is before end_at" do
|
||||
allow(subject).to receive(:start_at) { now.to_s }
|
||||
allow(subject).to receive(:end_at) { (now + 1.hour).to_s }
|
||||
|
||||
expect(subject).to be_valid
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "smoke authorization" do
|
||||
let!(:order_cycle) { create(:order_cycle) }
|
||||
let!(:user) { create(:user) }
|
||||
|
||||
let(:permissions) do
|
||||
report_klass::Permissions.new(nil).tap do |instance|
|
||||
instance.stub(allowed_order_cycles: [order_cycle])
|
||||
end
|
||||
end
|
||||
|
||||
it "does not raise error when the parameters are allowed" do
|
||||
parameters = described_class.new(order_cycle_ids: [order_cycle.id.to_s])
|
||||
expect { parameters.authorize!(permissions) }.not_to raise_error
|
||||
end
|
||||
|
||||
it "raises error when the parameters are not allowed" do
|
||||
parameters = described_class.new(order_cycle_ids: [(order_cycle.id + 1).to_s])
|
||||
expect { parameters.authorize!(permissions) }
|
||||
.to raise_error(Reports::Authorizer::ParameterNotAllowedError)
|
||||
end
|
||||
end
|
||||
|
||||
def report_klass
|
||||
OrderManagement::Reports::EnterpriseFeeSummary
|
||||
end
|
||||
end
|
||||
@@ -1,95 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "spec_helper"
|
||||
|
||||
describe OrderManagement::Reports::EnterpriseFeeSummary::Renderers::CsvRenderer do
|
||||
let(:report_klass) { OrderManagement::Reports::EnterpriseFeeSummary }
|
||||
|
||||
let!(:permissions) { report_klass::Permissions.new(current_user) }
|
||||
let!(:parameters) { report_klass::Parameters.new }
|
||||
let!(:service) { report_klass::ReportService.new(permissions, parameters) }
|
||||
let!(:renderer) { described_class.new(service) }
|
||||
|
||||
# Context which will be passed to the renderer. The response object is not automatically prepared,
|
||||
# so this has to be assigned explicitly.
|
||||
let!(:response) { ActionDispatch::TestResponse.new }
|
||||
let!(:request) { double(Rack::Request) }
|
||||
let!(:controller) do
|
||||
ActionController::Base.new.tap do |controller_mock|
|
||||
controller_mock.instance_variable_set(:@_response, response)
|
||||
controller_mock.instance_variable_set(:@_request, request)
|
||||
end
|
||||
end
|
||||
|
||||
let!(:enterprise_fee_type_totals) do
|
||||
[
|
||||
report_klass::ReportData::EnterpriseFeeTypeTotal.new(
|
||||
fee_type: "Fee Type A",
|
||||
enterprise_name: "Enterprise A",
|
||||
fee_name: "Fee A",
|
||||
customer_name: "Custoemr A",
|
||||
fee_placement: "Fee Placement A",
|
||||
fee_calculated_on_transfer_through_name: "Transfer Enterprise A",
|
||||
tax_category_name: "Tax Category A",
|
||||
total_amount: "1.00"
|
||||
),
|
||||
report_klass::ReportData::EnterpriseFeeTypeTotal.new(
|
||||
fee_type: "Fee Type B",
|
||||
enterprise_name: "Enterprise B",
|
||||
fee_name: "Fee C",
|
||||
customer_name: "Custoemr D",
|
||||
fee_placement: "Fee Placement E",
|
||||
fee_calculated_on_transfer_through_name: "Transfer Enterprise F",
|
||||
tax_category_name: "Tax Category G",
|
||||
total_amount: "2.00"
|
||||
)
|
||||
]
|
||||
end
|
||||
|
||||
let(:current_user) { nil }
|
||||
|
||||
before do
|
||||
allow(service).to receive(:list) { enterprise_fee_type_totals }
|
||||
allow(request).to receive_messages(variant: double(Spree::Variant),
|
||||
should_apply_vary_header?: true)
|
||||
end
|
||||
|
||||
it "generates CSV header" do
|
||||
renderer.render(controller)
|
||||
result = response.body
|
||||
csv = CSV.parse(result)
|
||||
header_row = csv[0]
|
||||
|
||||
# Test all header cells have values
|
||||
expect(header_row.length).to eq(8)
|
||||
expect(header_row.all?(&:present?)).to be_truthy
|
||||
end
|
||||
|
||||
it "generates CSV data rows" do
|
||||
renderer.render(controller)
|
||||
result = response.body
|
||||
csv = CSV.parse(result, headers: true)
|
||||
|
||||
expect(csv.length).to eq(2)
|
||||
|
||||
# Test random cells
|
||||
expect(csv[0][i18n_translate("header.fee_type")]).to eq("Fee Type A")
|
||||
expect(csv[0][i18n_translate("header.total_amount")]).to eq("1.00")
|
||||
expect(csv[1][i18n_translate("header.total_amount")]).to eq("2.00")
|
||||
end
|
||||
|
||||
it "generates filename correctly" do
|
||||
Timecop.freeze(Time.zone.local(2018, 10, 9, 7, 30, 0)) do
|
||||
filename = renderer.__send__(:filename)
|
||||
expect(filename).to eq("enterprise_fee_summary_20181009.csv")
|
||||
end
|
||||
end
|
||||
|
||||
def i18n_translate(key)
|
||||
I18n.t(key, scope: i18n_scope)
|
||||
end
|
||||
|
||||
def i18n_scope
|
||||
"order_management.reports.enterprise_fee_summary.formats.csv"
|
||||
end
|
||||
end
|
||||
@@ -1,72 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "spec_helper"
|
||||
|
||||
describe OrderManagement::Reports::EnterpriseFeeSummary::Renderers::HtmlRenderer do
|
||||
let(:report_klass) { OrderManagement::Reports::EnterpriseFeeSummary }
|
||||
|
||||
let!(:permissions) { report_klass::Permissions.new(current_user) }
|
||||
let!(:parameters) { report_klass::Parameters.new }
|
||||
let!(:controller) { OrderManagement::Reports::EnterpriseFeeSummariesController.new }
|
||||
let!(:service) { report_klass::ReportService.new(permissions, parameters) }
|
||||
let!(:renderer) { described_class.new(service) }
|
||||
|
||||
let!(:enterprise_fee_type_totals) do
|
||||
[
|
||||
report_klass::ReportData::EnterpriseFeeTypeTotal.new(
|
||||
fee_type: "Fee Type A",
|
||||
enterprise_name: "Enterprise A",
|
||||
fee_name: "Fee A",
|
||||
customer_name: "Custoemr A",
|
||||
fee_placement: "Fee Placement A",
|
||||
fee_calculated_on_transfer_through_name: "Transfer Enterprise A",
|
||||
tax_category_name: "Tax Category A",
|
||||
total_amount: "1.00"
|
||||
),
|
||||
report_klass::ReportData::EnterpriseFeeTypeTotal.new(
|
||||
fee_type: "Fee Type B",
|
||||
enterprise_name: "Enterprise B",
|
||||
fee_name: "Fee C",
|
||||
customer_name: "Custoemr D",
|
||||
fee_placement: "Fee Placement E",
|
||||
fee_calculated_on_transfer_through_name: "Transfer Enterprise F",
|
||||
tax_category_name: "Tax Category G",
|
||||
total_amount: "2.00"
|
||||
)
|
||||
]
|
||||
end
|
||||
|
||||
let(:current_user) { nil }
|
||||
|
||||
before do
|
||||
allow(service).to receive(:list) { enterprise_fee_type_totals }
|
||||
end
|
||||
|
||||
it "generates header values" do
|
||||
header_row = renderer.header
|
||||
|
||||
# Test all header cells have values
|
||||
expect(header_row.length).to eq(8)
|
||||
expect(header_row.all?(&:present?)).to be_truthy
|
||||
end
|
||||
|
||||
it "generates data rows" do
|
||||
header_row = renderer.header
|
||||
result = renderer.data_rows
|
||||
|
||||
expect(result.length).to eq(2)
|
||||
|
||||
# Test random cells
|
||||
expect(result[0][header_row.index(i18n_translate("header.fee_type"))]).to eq("Fee Type A")
|
||||
expect(result[0][header_row.index(i18n_translate("header.total_amount"))]).to eq("1.00")
|
||||
expect(result[1][header_row.index(i18n_translate("header.total_amount"))]).to eq("2.00")
|
||||
end
|
||||
|
||||
def i18n_translate(key)
|
||||
I18n.t(key, scope: i18n_scope)
|
||||
end
|
||||
|
||||
def i18n_scope
|
||||
"order_management.reports.enterprise_fee_summary.formats.csv"
|
||||
end
|
||||
end
|
||||
@@ -1,99 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module OpenFoodNetwork
|
||||
class CustomersReport
|
||||
attr_reader :params
|
||||
|
||||
def initialize(user, params = {}, compile_table = false)
|
||||
@params = params
|
||||
@user = user
|
||||
@compile_table = compile_table
|
||||
end
|
||||
|
||||
def header
|
||||
if is_mailing_list?
|
||||
[I18n.t(:report_header_email),
|
||||
I18n.t(:report_header_first_name),
|
||||
I18n.t(:report_header_last_name),
|
||||
I18n.t(:report_header_suburb)]
|
||||
else
|
||||
[I18n.t(:report_header_first_name),
|
||||
I18n.t(:report_header_last_name),
|
||||
I18n.t(:report_header_billing_address),
|
||||
I18n.t(:report_header_email),
|
||||
I18n.t(:report_header_phone),
|
||||
I18n.t(:report_header_hub),
|
||||
I18n.t(:report_header_hub_address),
|
||||
I18n.t(:report_header_shipping_method)]
|
||||
end
|
||||
end
|
||||
|
||||
def table
|
||||
return [] unless @compile_table
|
||||
|
||||
orders.map do |order|
|
||||
if is_mailing_list?
|
||||
[order.email,
|
||||
order.billing_address.firstname,
|
||||
order.billing_address.lastname,
|
||||
order.billing_address.city]
|
||||
else
|
||||
ba = order.billing_address
|
||||
da = order.distributor&.address
|
||||
[ba.firstname,
|
||||
ba.lastname,
|
||||
[ba.address1, ba.address2, ba.city].join(" "),
|
||||
order.email,
|
||||
ba.phone,
|
||||
order.distributor&.name,
|
||||
[da&.address1, da&.address2, da&.city].join(" "),
|
||||
order.shipping_method&.name]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def orders
|
||||
filter Spree::Order.managed_by(@user).distributed_by_user(@user).complete.not_state(:canceled)
|
||||
end
|
||||
|
||||
def filter(orders)
|
||||
filter_to_supplier filter_to_distributor filter_to_order_cycle orders
|
||||
end
|
||||
|
||||
def filter_to_supplier(orders)
|
||||
if params[:supplier_id].to_i > 0
|
||||
orders.select do |order|
|
||||
order.line_items.includes(:product)
|
||||
.where("spree_products.supplier_id = ?", params[:supplier_id].to_i)
|
||||
.references(:product)
|
||||
.count
|
||||
.positive?
|
||||
end
|
||||
else
|
||||
orders
|
||||
end
|
||||
end
|
||||
|
||||
def filter_to_distributor(orders)
|
||||
if params[:distributor_id].to_i > 0
|
||||
orders.where(distributor_id: params[:distributor_id])
|
||||
else
|
||||
orders
|
||||
end
|
||||
end
|
||||
|
||||
def filter_to_order_cycle(orders)
|
||||
if params[:order_cycle_id].to_i > 0
|
||||
orders.where(order_cycle_id: params[:order_cycle_id])
|
||||
else
|
||||
orders
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def is_mailing_list?
|
||||
params[:report_type] == "mailing_list"
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,71 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module OpenFoodNetwork
|
||||
GroupBuyVariantRow = Struct.new(:variant, :sum_quantities, :sum_max_quantities) do
|
||||
def to_row
|
||||
[variant.product.supplier.name, variant.product.name, I18n.t('admin.reports.unitsize'),
|
||||
variant.options_text, variant.weight, sum_quantities, sum_max_quantities]
|
||||
end
|
||||
end
|
||||
|
||||
GroupBuyProductRow = Struct.new(:product, :sum_quantities, :sum_max_quantities) do
|
||||
def to_row
|
||||
[product.supplier.name, product.name, I18n.t('admin.reports.unitsize'),
|
||||
I18n.t('admin.reports.total'), "", sum_quantities, sum_max_quantities]
|
||||
end
|
||||
end
|
||||
|
||||
class GroupBuyReport
|
||||
def initialize(orders)
|
||||
@orders = orders
|
||||
end
|
||||
|
||||
def header
|
||||
[
|
||||
I18n.t(:report_header_supplier),
|
||||
I18n.t(:report_header_product),
|
||||
I18n.t(:report_header_unit_size),
|
||||
I18n.t(:report_header_variant),
|
||||
I18n.t(:report_header_weight),
|
||||
I18n.t(:report_header_total_ordered),
|
||||
I18n.t(:report_header_total_max),
|
||||
]
|
||||
end
|
||||
|
||||
def variants_and_quantities
|
||||
variants_and_quantities = []
|
||||
line_items = @orders.map(&:line_items).flatten
|
||||
supplier_groups = line_items.group_by { |li| li.variant.product.supplier }
|
||||
supplier_groups.each do |_supplier, line_items_by_supplier|
|
||||
product_groups = line_items_by_supplier.group_by { |li| li.variant.product }
|
||||
product_groups.each do |product, line_items_by_product|
|
||||
# Cycle thorugh variant of a product
|
||||
variant_groups = line_items_by_product.group_by(&:variant)
|
||||
variant_groups.each do |variant, line_items_by_variant|
|
||||
sum_quantities = line_items_by_variant.to_a.sum(&:quantity)
|
||||
sum_max_quantities = line_items_by_variant.sum { |li| li.max_quantity || 0 }
|
||||
variants_and_quantities << GroupBuyVariantRow.new(variant, sum_quantities,
|
||||
sum_max_quantities)
|
||||
end
|
||||
|
||||
# Sum quantities for each product (Total line)
|
||||
sum_quantities = line_items_by_product.sum { |li| (li.variant.weight || 0) * li.quantity }
|
||||
sum_max_quantities = line_items_by_product.sum { |li|
|
||||
(li.variant.weight || 0) * (li.max_quantity || 0)
|
||||
}
|
||||
variants_and_quantities << GroupBuyProductRow.new(product, sum_quantities,
|
||||
sum_max_quantities)
|
||||
end
|
||||
end
|
||||
variants_and_quantities
|
||||
end
|
||||
|
||||
def table
|
||||
table = []
|
||||
variants_and_quantities.each do |vr|
|
||||
table << vr.to_row
|
||||
end
|
||||
table
|
||||
end
|
||||
end
|
||||
end
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user