Run rubocop --fix-layout and remove encoding comments

This commit is contained in:
Patrick Gansterer 2021-03-01 15:27:26 +01:00
parent fa63e6e81d
commit ea2862fdef
283 changed files with 1164 additions and 1969 deletions

View file

@ -29,491 +29,6 @@ Gemspec/RequiredRubyVersion:
- 'plugins/uservoice/foodsoft_uservoice.gemspec' - 'plugins/uservoice/foodsoft_uservoice.gemspec'
- 'plugins/wiki/foodsoft_wiki.gemspec' - 'plugins/wiki/foodsoft_wiki.gemspec'
# Offense count: 5
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, IndentationWidth.
# SupportedStyles: outdent, indent
Layout/AccessModifierIndentation:
Exclude:
- 'app/controllers/finance/financial_links_controller.rb'
- 'app/models/invite.rb'
- 'db/migrate/20130622095040_move_weekly_tasks.rb'
# Offense count: 13
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, IndentationWidth.
# SupportedStyles: with_first_argument, with_fixed_indentation
Layout/ArgumentAlignment:
Exclude:
- 'app/controllers/finance/balancing_controller.rb'
- 'app/controllers/foodcoop/workgroups_controller.rb'
- 'app/helpers/deliveries_helper.rb'
- 'app/helpers/stockit_helper.rb'
- 'db/migrate/20140102170431_add_result_computed_to_group_order_articles.rb'
- 'plugins/discourse/app/controllers/discourse_login_controller.rb'
- 'plugins/discourse/app/controllers/discourse_sso_controller.rb'
- 'plugins/messages/lib/foodsoft_messages/user_link.rb'
- 'plugins/polls/app/controllers/polls_controller.rb'
- 'spec/models/user_spec.rb'
# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, IndentationWidth.
# SupportedStyles: with_first_element, with_fixed_indentation
Layout/ArrayAlignment:
Exclude:
- 'lib/render_pdf.rb'
# Offense count: 3
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyleAlignWith.
# SupportedStylesAlignWith: either, start_of_block, start_of_line
Layout/BlockAlignment:
Exclude:
- 'db/migrate/008_create_orders.rb'
- 'db/migrate/20090120184410_road_to_version_three.rb'
- 'spec/api/v1/user/group_order_articles_spec.rb'
# Offense count: 86
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, IndentOneStep, IndentationWidth.
# SupportedStyles: case, end
Layout/CaseIndentation:
Enabled: false
# Offense count: 5
# Cop supports --auto-correct.
Layout/ClosingParenthesisIndentation:
Exclude:
- 'app/helpers/stockit_helper.rb'
- 'app/models/group_order_article.rb'
- 'app/models/shared_article.rb'
- 'db/seeds/minimal.seeds.rb'
# Offense count: 4
# Cop supports --auto-correct.
Layout/CommentIndentation:
Exclude:
- 'app/controllers/concerns/auth_api.rb'
- 'app/controllers/finance/financial_transactions_controller.rb'
- 'app/documents/order_fax.rb'
- 'db/migrate/20090120184410_road_to_version_three.rb'
# Offense count: 51
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: leading, trailing
Layout/DotPosition:
Exclude:
- 'app/controllers/api/v1/user/group_order_articles_controller.rb'
- 'app/controllers/stockit_controller.rb'
- 'app/documents/order_fax.rb'
- 'app/models/order.rb'
- 'app/models/stock_article.rb'
- 'app/models/task.rb'
- 'lib/order_pdf.rb'
- 'plugins/current_orders/app/controllers/current_orders/group_orders_controller.rb'
- 'plugins/current_orders/app/controllers/current_orders/ordergroups_controller.rb'
- 'plugins/current_orders/app/documents/multiple_orders_by_articles.rb'
- 'plugins/current_orders/app/documents/multiple_orders_by_groups.rb'
# Offense count: 3
# Cop supports --auto-correct.
Layout/ElseAlignment:
Exclude:
- 'app/helpers/group_orders_helper.rb'
# Offense count: 70
# Cop supports --auto-correct.
Layout/EmptyLineAfterGuardClause:
Enabled: false
# Offense count: 38
# Cop supports --auto-correct.
Layout/EmptyLineAfterMagicComment:
Enabled: false
# Offense count: 15
# Cop supports --auto-correct.
# Configuration parameters: EmptyLineBetweenMethodDefs, EmptyLineBetweenClassDefs, EmptyLineBetweenModuleDefs, AllowAdjacentOneLineDefs, NumberOfEmptyLines.
Layout/EmptyLineBetweenDefs:
Exclude:
- 'app/helpers/finance/invoices_helper.rb'
- 'app/helpers/orders_helper.rb'
- 'app/models/group_order.rb'
- 'app/models/ordergroup.rb'
- 'app/models/task.rb'
- 'db/migrate/20181201000400_create_supplier_categories.rb'
- 'db/migrate/20181204000000_clear_invalid_invoices_from_orders.rb'
- 'db/migrate/20181204070000_create_stock_events.rb'
- 'lib/api/errors.rb'
- 'lib/foodsoft/expansion_variables.rb'
- 'lib/token_verifier.rb'
- 'plugins/wiki/app/helpers/pages_helper.rb'
- 'spec/support/shared_database.rb'
# Offense count: 55
# Cop supports --auto-correct.
Layout/EmptyLines:
Enabled: false
# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: around, only_before
Layout/EmptyLinesAroundAccessModifier:
Exclude:
- 'db/migrate/20130622095040_move_weekly_tasks.rb'
# Offense count: 85
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: empty_lines, no_empty_lines
Layout/EmptyLinesAroundBlockBody:
Enabled: false
# Offense count: 147
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: empty_lines, empty_lines_except_namespace, empty_lines_special, no_empty_lines, beginning_only, ending_only
Layout/EmptyLinesAroundClassBody:
Enabled: false
# Offense count: 3
# Cop supports --auto-correct.
Layout/EmptyLinesAroundExceptionHandlingKeywords:
Exclude:
- 'app/controllers/articles_controller.rb'
- 'app/controllers/finance/balancing_controller.rb'
- 'plugins/wiki/app/controllers/pages_controller.rb'
# Offense count: 2
# Cop supports --auto-correct.
Layout/EmptyLinesAroundMethodBody:
Exclude:
- 'app/helpers/application_helper.rb'
- 'db/migrate/002_create_groups.rb'
# Offense count: 37
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: empty_lines, empty_lines_except_namespace, empty_lines_special, no_empty_lines
Layout/EmptyLinesAroundModuleBody:
Enabled: false
# Offense count: 9
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyleAlignWith, Severity.
# SupportedStylesAlignWith: keyword, variable, start_of_line
Layout/EndAlignment:
Exclude:
- 'app/controllers/articles_controller.rb'
- 'app/controllers/concerns/auth.rb'
- 'app/controllers/concerns/send_order_pdf.rb'
- 'app/controllers/finance/financial_transactions_controller.rb'
- 'app/controllers/home_controller.rb'
- 'app/controllers/orders_controller.rb'
- 'app/helpers/group_orders_helper.rb'
- 'plugins/wiki/app/controllers/pages_controller.rb'
# Offense count: 57
# Cop supports --auto-correct.
# Configuration parameters: AllowForAlignment, AllowBeforeTrailingComments, ForceEqualSignAlignment.
Layout/ExtraSpacing:
Enabled: false
# Offense count: 6
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, IndentationWidth.
# SupportedStyles: consistent, consistent_relative_to_receiver, special_for_inner_method_call, special_for_inner_method_call_in_parentheses
Layout/FirstArgumentIndentation:
Exclude:
- 'app/models/group_order_article.rb'
- 'app/models/shared_article.rb'
- 'db/seeds/minimal.seeds.rb'
- 'plugins/current_orders/app/controllers/current_orders/articles_controller.rb'
- 'plugins/current_orders/app/controllers/current_orders/ordergroups_controller.rb'
# Offense count: 8
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, IndentationWidth.
# SupportedStyles: special_inside_parentheses, consistent, align_brackets
Layout/FirstArrayElementIndentation:
Exclude:
- 'db/seeds/small.en.seeds.rb'
- 'db/seeds/small.nl.seeds.rb'
- 'lib/financial_transactions_csv.rb'
- 'lib/order_csv.rb'
# Offense count: 9
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, IndentationWidth.
# SupportedStyles: special_inside_parentheses, consistent, align_braces
Layout/FirstHashElementIndentation:
Exclude:
- 'app/controllers/finance/financial_transactions_controller.rb'
- 'app/helpers/application_helper.rb'
- 'app/models/group_order.rb'
- 'db/migrate/20130718183101_migrate_user_settings.rb'
- 'lib/bank_account_information_importer.rb'
# Offense count: 83
# Cop supports --auto-correct.
# Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle.
# SupportedHashRocketStyles: key, separator, table
# SupportedColonStyles: key, separator, table
# SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit
Layout/HashAlignment:
Enabled: false
# Offense count: 9
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: normal, indented_internal_methods
Layout/IndentationConsistency:
Exclude:
- 'db/migrate/003_create_suppliers.rb'
- 'db/migrate/007_create_article_prices.rb'
- 'db/migrate/008_create_orders.rb'
- 'db/migrate/010_user_password_reset.rb'
- 'db/migrate/20090120184410_road_to_version_three.rb'
# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: IndentationWidth, EnforcedStyle.
# SupportedStyles: spaces, tabs
Layout/IndentationStyle:
Exclude:
- 'db/migrate/010_user_password_reset.rb'
# Offense count: 12
# Cop supports --auto-correct.
# Configuration parameters: Width, IgnoredPatterns.
Layout/IndentationWidth:
Exclude:
- 'app/helpers/admin/configs_helper.rb'
- 'app/helpers/group_orders_helper.rb'
- 'app/models/user.rb'
- 'db/migrate/003_create_suppliers.rb'
- 'db/migrate/007_create_article_prices.rb'
- 'db/migrate/008_create_orders.rb'
- 'db/migrate/20090120184410_road_to_version_three.rb'
- 'lib/tasks/multicoops.rake'
- 'spec/api/v1/user/group_order_articles_spec.rb'
- 'spec/spec_helper.rb'
# Offense count: 39
# Cop supports --auto-correct.
# Configuration parameters: AllowDoxygenCommentStyle, AllowGemfileRubyComment.
Layout/LeadingCommentSpace:
Enabled: false
# Offense count: 5
# Cop supports --auto-correct.
Layout/LeadingEmptyLines:
Exclude:
- 'db/migrate/20090120184410_road_to_version_three.rb'
- 'db/seeds/seed_helper.rb'
- 'lib/order_txt.rb'
- 'spec/support/integration.rb'
- 'spec/support/session_helper.rb'
# Offense count: 2
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: symmetrical, new_line, same_line
Layout/MultilineMethodCallBraceLayout:
Exclude:
- 'app/helpers/stockit_helper.rb'
# Offense count: 42
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, IndentationWidth.
# SupportedStyles: aligned, indented, indented_relative_to_receiver
Layout/MultilineMethodCallIndentation:
Exclude:
- 'app/controllers/stockit_controller.rb'
- 'app/models/order.rb'
- 'app/models/ordergroup.rb'
- 'app/models/stock_article.rb'
- 'app/models/task.rb'
- 'lib/foodsoft/expansion_variables.rb'
- 'lib/order_pdf.rb'
- 'plugins/current_orders/app/controllers/current_orders/group_orders_controller.rb'
- 'plugins/current_orders/app/controllers/current_orders/ordergroups_controller.rb'
- 'plugins/current_orders/app/documents/multiple_orders_by_groups.rb'
- 'spec/api/v1/user/group_order_articles_spec.rb'
# Offense count: 9
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, IndentationWidth.
# SupportedStyles: aligned, indented
Layout/MultilineOperationIndentation:
Exclude:
- 'app/helpers/orders_helper.rb'
- 'app/inputs/date_picker_time_input.rb'
- 'app/models/ordergroup.rb'
- 'app/models/task.rb'
- 'lib/apple_bar.rb'
# Offense count: 1
# Cop supports --auto-correct.
Layout/RescueEnsureAlignment:
Exclude:
- 'app/controllers/suppliers_controller.rb'
# Offense count: 9
# Cop supports --auto-correct.
Layout/SpaceAfterColon:
Exclude:
- 'app/controllers/styles_controller.rb'
- 'spec/integration/articles_spec.rb'
- 'spec/integration/balancing_spec.rb'
- 'spec/integration/order_spec.rb'
- 'spec/integration/receive_spec.rb'
- 'spec/integration/supplier_spec.rb'
- 'spec/models/order_article_spec.rb'
- 'spec/models/ordergroup_spec.rb'
# Offense count: 110
# Cop supports --auto-correct.
Layout/SpaceAfterComma:
Enabled: false
# Offense count: 8
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyleInsidePipes.
# SupportedStylesInsidePipes: space, no_space
Layout/SpaceAroundBlockParameters:
Exclude:
- 'app/models/group_order_article.rb'
- 'db/migrate/008_create_orders.rb'
# Offense count: 50
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: space, no_space
Layout/SpaceAroundEqualsInParameterDefault:
Enabled: false
# Offense count: 109
# Cop supports --auto-correct.
# Configuration parameters: AllowForAlignment, EnforcedStyleForExponentOperator.
# SupportedStylesForExponentOperator: space, no_space
Layout/SpaceAroundOperators:
Enabled: false
# Offense count: 73
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces.
# SupportedStyles: space, no_space
# SupportedStylesForEmptyBraces: space, no_space
Layout/SpaceBeforeBlockBraces:
Enabled: false
# Offense count: 2
# Cop supports --auto-correct.
Layout/SpaceBeforeComma:
Exclude:
- 'db/migrate/016_add_shared_lists_connection.rb'
- 'lib/render_pdf.rb'
# Offense count: 1
# Cop supports --auto-correct.
Layout/SpaceBeforeComment:
Exclude:
- 'plugins/wiki/lib/foodsoft_wiki/wiki_parser.rb'
# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: AllowForAlignment.
Layout/SpaceBeforeFirstArg:
Exclude:
- 'app/controllers/application_controller.rb'
# Offense count: 2
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: require_no_space, require_space
Layout/SpaceInLambdaLiteral:
Exclude:
- 'plugins/messages/app/models/message.rb'
# Offense count: 7
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBrackets.
# SupportedStyles: space, no_space, compact
# SupportedStylesForEmptyBrackets: space, no_space
Layout/SpaceInsideArrayLiteralBrackets:
Exclude:
- 'app/helpers/orders_helper.rb'
- 'config/application.rb'
- 'config/environments/production.rb'
- 'db/migrate/20130718183100_create_settings.rb'
# Offense count: 148
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces, SpaceBeforeBlockParameters.
# SupportedStyles: space, no_space
# SupportedStylesForEmptyBraces: space, no_space
Layout/SpaceInsideBlockBraces:
Enabled: false
# Offense count: 374
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces.
# SupportedStyles: space, no_space, compact
# SupportedStylesForEmptyBraces: space, no_space
Layout/SpaceInsideHashLiteralBraces:
Enabled: false
# Offense count: 6
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: space, no_space
Layout/SpaceInsideParens:
Exclude:
- 'app/helpers/group_orders_helper.rb'
- 'db/migrate/006_create_articles.rb'
- 'spec/api/v1/user/group_order_articles_spec.rb'
# Offense count: 14
# Cop supports --auto-correct.
Layout/SpaceInsidePercentLiteralDelimiters:
Exclude:
- 'lib/tasks/foodsoft_setup.rake'
# Offense count: 7
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBrackets.
# SupportedStyles: space, no_space
# SupportedStylesForEmptyBrackets: space, no_space
Layout/SpaceInsideReferenceBrackets:
Exclude:
- 'lib/bank_account_information_importer.rb'
- 'lib/foodsoft_config.rb'
- 'spec/api/v1/user/ordergroup_spec.rb'
# Offense count: 7
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: final_newline, final_blank_line
Layout/TrailingEmptyLines:
Exclude:
- 'app/models/ordergroup.rb'
- 'config/initializers/bullet.rb'
- 'config/initializers/new_rails_defaults.rb'
- 'db/migrate/20130718183101_migrate_user_settings.rb'
- 'lib/apple_bar.rb'
- 'lib/tasks/foodsoft_setup.rake'
- 'spec/support/faker.rb'
# Offense count: 111
# Cop supports --auto-correct.
# Configuration parameters: AllowInHeredoc.
Layout/TrailingWhitespace:
Enabled: false
# Offense count: 8 # Offense count: 8
Lint/AmbiguousBlockAssociation: Lint/AmbiguousBlockAssociation:
Exclude: Exclude:
@ -529,13 +44,12 @@ Lint/AmbiguousOperator:
- 'app/mailers/mailer.rb' - 'app/mailers/mailer.rb'
- 'spec/models/order_article_spec.rb' - 'spec/models/order_article_spec.rb'
# Offense count: 3 # Offense count: 2
# Cop supports --auto-correct. # Cop supports --auto-correct.
Lint/AmbiguousRegexpLiteral: Lint/AmbiguousRegexpLiteral:
Exclude: Exclude:
- 'app/models/article_category.rb' - 'app/models/article_category.rb'
- 'lib/foodsoft/expansion_variables.rb' - 'lib/foodsoft/expansion_variables.rb'
- 'lib/foodsoft_config.rb'
# Offense count: 40 # Offense count: 40
# Configuration parameters: AllowSafeAssignment. # Configuration parameters: AllowSafeAssignment.
@ -626,7 +140,7 @@ Lint/ParenthesesAsGroupedExpression:
- 'spec/lib/token_verifier_spec.rb' - 'spec/lib/token_verifier_spec.rb'
- 'spec/models/order_article_spec.rb' - 'spec/models/order_article_spec.rb'
# Offense count: 2 # Offense count: 1
Lint/ReturnInVoidContext: Lint/ReturnInVoidContext:
Exclude: Exclude:
- 'lib/foodsoft_config.rb' - 'lib/foodsoft_config.rb'
@ -721,12 +235,11 @@ Lint/UnusedMethodArgument:
- 'lib/render_pdf.rb' - 'lib/render_pdf.rb'
- 'plugins/wiki/lib/foodsoft_wiki/mailer.rb' - 'plugins/wiki/lib/foodsoft_wiki/mailer.rb'
# Offense count: 3 # Offense count: 2
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: ContextCreatingMethods, MethodCreatingMethods. # Configuration parameters: ContextCreatingMethods, MethodCreatingMethods.
Lint/UselessAccessModifier: Lint/UselessAccessModifier:
Exclude: Exclude:
- 'lib/foodsoft_config.rb'
- 'lib/token_verifier.rb' - 'lib/token_verifier.rb'
- 'plugins/messages/app/models/messagegroup.rb' - 'plugins/messages/app/models/messagegroup.rb'
@ -746,6 +259,12 @@ Lint/UselessAssignment:
- 'plugins/current_orders/app/documents/multiple_orders_by_groups.rb' - 'plugins/current_orders/app/documents/multiple_orders_by_groups.rb'
- 'spec/lib/foodsoft_config_spec.rb' - 'spec/lib/foodsoft_config_spec.rb'
# Offense count: 1
# Configuration parameters: CheckForMethodsWithNoSideEffects.
Lint/Void:
Exclude:
- 'lib/foodsoft_config.rb'
# Offense count: 158 # Offense count: 158
# Configuration parameters: IgnoredMethods, CountRepeatedAttributes. # Configuration parameters: IgnoredMethods, CountRepeatedAttributes.
Metrics/AbcSize: Metrics/AbcSize:
@ -1082,7 +601,7 @@ RSpec/MultipleMemoizedHelpers:
RSpec/NestedGroups: RSpec/NestedGroups:
Max: 6 Max: 6
# Offense count: 32 # Offense count: 31
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle. # Configuration parameters: EnforcedStyle.
# SupportedStyles: not_to, to_not # SupportedStyles: not_to, to_not
@ -1092,7 +611,6 @@ RSpec/NotToNot:
- 'spec/api/v1/user/group_order_articles_spec.rb' - 'spec/api/v1/user/group_order_articles_spec.rb'
- 'spec/integration/balancing_spec.rb' - 'spec/integration/balancing_spec.rb'
- 'spec/integration/login_spec.rb' - 'spec/integration/login_spec.rb'
- 'spec/integration/order_spec.rb'
- 'spec/integration/receive_spec.rb' - 'spec/integration/receive_spec.rb'
- 'spec/integration/session_spec.rb' - 'spec/integration/session_spec.rb'
- 'spec/lib/token_verifier_spec.rb' - 'spec/lib/token_verifier_spec.rb'
@ -1520,14 +1038,13 @@ Security/YAMLLoad:
- 'lib/foodsoft_config.rb' - 'lib/foodsoft_config.rb'
- 'spec/api/v1/swagger_spec.rb' - 'spec/api/v1/swagger_spec.rb'
# Offense count: 4 # Offense count: 3
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle. # Configuration parameters: EnforcedStyle.
# SupportedStyles: prefer_alias, prefer_alias_method # SupportedStyles: prefer_alias, prefer_alias_method
Style/Alias: Style/Alias:
Exclude: Exclude:
- 'config/initializers/session_store.rb' - 'config/initializers/session_store.rb'
- 'lib/foodsoft_config.rb'
- 'plugins/discourse/lib/foodsoft_discourse/redirect_to_login.rb' - 'plugins/discourse/lib/foodsoft_discourse/redirect_to_login.rb'
- 'plugins/printer/lib/foodsoft_printer/order_printer_jobs.rb' - 'plugins/printer/lib/foodsoft_printer/order_printer_jobs.rb'
@ -1685,7 +1202,7 @@ Style/DefWithParentheses:
Exclude: Exclude:
- 'app/models/user.rb' - 'app/models/user.rb'
# Offense count: 306 # Offense count: 307
Style/Documentation: Style/Documentation:
Enabled: false Enabled: false
@ -1735,11 +1252,6 @@ Style/EmptyMethod:
- 'db/migrate/20140318173000_delete_empty_group_order_articles.rb' - 'db/migrate/20140318173000_delete_empty_group_order_articles.rb'
- 'lib/bank_account_connector.rb' - 'lib/bank_account_connector.rb'
# Offense count: 40
# Cop supports --auto-correct.
Style/Encoding:
Enabled: false
# Offense count: 21 # Offense count: 21
# Cop supports --auto-correct. # Cop supports --auto-correct.
Style/ExpandPathArguments: Style/ExpandPathArguments:
@ -1809,7 +1321,7 @@ Style/GlobalStdStream:
- 'lib/tasks/foodsoft.rake' - 'lib/tasks/foodsoft.rake'
- 'lib/tasks/foodsoft_setup.rake' - 'lib/tasks/foodsoft_setup.rake'
# Offense count: 63 # Offense count: 62
# Configuration parameters: MinBodyLength. # Configuration parameters: MinBodyLength.
Style/GuardClause: Style/GuardClause:
Enabled: false Enabled: false
@ -1822,7 +1334,7 @@ Style/HashAsLastArrayItem:
Exclude: Exclude:
- 'app/models/order.rb' - 'app/models/order.rb'
# Offense count: 7 # Offense count: 6
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: AllowSplatArgument. # Configuration parameters: AllowSplatArgument.
Style/HashConversion: Style/HashConversion:
@ -1831,7 +1343,6 @@ Style/HashConversion:
- 'app/models/article.rb' - 'app/models/article.rb'
- 'app/models/order.rb' - 'app/models/order.rb'
- 'lib/bank_account_information_importer.rb' - 'lib/bank_account_information_importer.rb'
- 'lib/foodsoft_config.rb'
- 'plugins/wiki/app/controllers/pages_controller.rb' - 'plugins/wiki/app/controllers/pages_controller.rb'
- 'spec/api/v1/user/ordergroup_spec.rb' - 'spec/api/v1/user/ordergroup_spec.rb'
@ -2201,7 +1712,7 @@ Style/RedundantRegexpEscape:
- 'plugins/documents/app/controllers/documents_controller.rb' - 'plugins/documents/app/controllers/documents_controller.rb'
- 'plugins/wiki/app/models/page.rb' - 'plugins/wiki/app/models/page.rb'
# Offense count: 18 # Offense count: 15
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: AllowMultipleReturnValues. # Configuration parameters: AllowMultipleReturnValues.
Style/RedundantReturn: Style/RedundantReturn:
@ -2216,7 +1727,6 @@ Style/RedundantReturn:
- 'app/models/periodic_task_group.rb' - 'app/models/periodic_task_group.rb'
- 'app/models/supplier.rb' - 'app/models/supplier.rb'
- 'lib/bank_transaction_reference.rb' - 'lib/bank_transaction_reference.rb'
- 'lib/foodsoft_config.rb'
# Offense count: 85 # Offense count: 85
# Cop supports --auto-correct. # Cop supports --auto-correct.
@ -2435,9 +1945,9 @@ Style/ZeroLengthPredicate:
- 'plugins/current_orders/app/documents/multiple_orders_by_articles.rb' - 'plugins/current_orders/app/documents/multiple_orders_by_articles.rb'
- 'plugins/current_orders/app/documents/multiple_orders_by_groups.rb' - 'plugins/current_orders/app/documents/multiple_orders_by_groups.rb'
# Offense count: 436 # Offense count: 447
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: AutoCorrect, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns. # Configuration parameters: AutoCorrect, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
# URISchemes: http, https # URISchemes: http, https
Layout/LineLength: Layout/LineLength:
Max: 414 Max: 420

View file

@ -9,7 +9,6 @@ gem 'uglifier', '>= 1.0.3'
# See https://github.com/sstephenson/execjs#readme for more supported runtimes # See https://github.com/sstephenson/execjs#readme for more supported runtimes
gem 'therubyracer', platforms: :ruby gem 'therubyracer', platforms: :ruby
gem 'jquery-rails' gem 'jquery-rails'
gem 'select2-rails' gem 'select2-rails'
gem 'rails_tokeninput' gem 'rails_tokeninput'
@ -67,10 +66,9 @@ gem 'foodsoft_links', path: 'plugins/links'
gem 'foodsoft_polls', path: 'plugins/polls' gem 'foodsoft_polls', path: 'plugins/polls'
# plugins not enabled by default # plugins not enabled by default
#gem 'foodsoft_current_orders', path: 'plugins/current_orders' # gem 'foodsoft_current_orders', path: 'plugins/current_orders'
#gem 'foodsoft_printer', path: 'plugins/printer' # gem 'foodsoft_printer', path: 'plugins/printer'
#gem 'foodsoft_uservoice', path: 'plugins/uservoice' # gem 'foodsoft_uservoice', path: 'plugins/uservoice'
group :development do group :development do
gem 'sqlite3', '~> 1.3.6' gem 'sqlite3', '~> 1.3.6'

View file

@ -6,5 +6,4 @@ class Admin::BaseController < ApplicationController
@groups = Group.where(deleted_at: nil).order('created_on DESC').limit(10) @groups = Group.where(deleted_at: nil).order('created_on DESC').limit(10)
@users = User.order('created_on DESC').limit(10) @users = User.order('created_on DESC').limit(10)
end end
end end

View file

@ -1,5 +1,4 @@
class Admin::ConfigsController < Admin::BaseController class Admin::ConfigsController < Admin::BaseController
before_action :get_tabs, only: [:show, :list] before_action :get_tabs, only: [:show, :list]
def show def show
@ -11,7 +10,7 @@ class Admin::ConfigsController < Admin::BaseController
@current_tab = 'list' @current_tab = 'list'
@cfg = FoodsoftConfig @cfg = FoodsoftConfig
@dfl = FoodsoftConfig.config @dfl = FoodsoftConfig.config
@keys = FoodsoftConfig.keys.select {|k| FoodsoftConfig.allowed_key?(k)}.sort @keys = FoodsoftConfig.keys.select { |k| FoodsoftConfig.allowed_key?(k) }.sort
end end
def update def update
@ -56,10 +55,9 @@ class Admin::ConfigsController < Admin::BaseController
def convert_config_value(value) def convert_config_value(value)
if value.is_a? ActionController::Parameters if value.is_a? ActionController::Parameters
value.transform_values{ |v| convert_config_value(v) }.to_hash value.transform_values { |v| convert_config_value(v) }.to_hash
else else
value value
end end
end end
end end

View file

@ -15,5 +15,4 @@ class Admin::FinancesController < Admin::BaseController
@financial_transaction_classes = FinancialTransactionClass.includes(:financial_transaction_types).order('name ASC') @financial_transaction_classes = FinancialTransactionClass.includes(:financial_transaction_types).order('name ASC')
render :layout => false render :layout => false
end end
end end

View file

@ -1,4 +1,3 @@
# encoding: utf-8
class Admin::OrdergroupsController < Admin::BaseController class Admin::OrdergroupsController < Admin::BaseController
inherit_resources inherit_resources

View file

@ -1,4 +1,3 @@
# encoding: utf-8
class Admin::WorkgroupsController < Admin::BaseController class Admin::WorkgroupsController < Admin::BaseController
inherit_resources inherit_resources

View file

@ -22,5 +22,4 @@ class Api::V1::ArticleCategoriesController < Api::V1::BaseController
def scope def scope
ArticleCategory.all ArticleCategory.all
end end
end end

View file

@ -51,26 +51,26 @@ class Api::V1::BaseController < ApplicationController
def not_found_handler(e) def not_found_handler(e)
# remove where-clauses from error message (not suitable for end-users) # remove where-clauses from error message (not suitable for end-users)
msg = e.message.try {|m| m.sub(/\s*\[.*?\]\s*$/, '')} || 'Not found' msg = e.message.try { |m| m.sub(/\s*\[.*?\]\s*$/, '') } || 'Not found'
render status: 404, json: {error: 'not_found', error_description: msg} render status: 404, json: { error: 'not_found', error_description: msg }
end end
def not_acceptable_handler(e) def not_acceptable_handler(e)
msg = e.message || 'Data not acceptable' msg = e.message || 'Data not acceptable'
render status: 422, json: {error: 'not_acceptable', error_description: msg} render status: 422, json: { error: 'not_acceptable', error_description: msg }
end end
def doorkeeper_unauthorized_render_options(error:) def doorkeeper_unauthorized_render_options(error:)
{json: {error: error.name, error_description: error.description}} { json: { error: error.name, error_description: error.description } }
end end
def doorkeeper_forbidden_render_options(error:) def doorkeeper_forbidden_render_options(error:)
{json: {error: error.name, error_description: error.description}} { json: { error: error.name, error_description: error.description } }
end end
def permission_required_handler(e) def permission_required_handler(e)
msg = e.message || 'Forbidden, user has no access' msg = e.message || 'Forbidden, user has no access'
render status: 403, json: {error: 'forbidden', error_description: msg} render status: 403, json: { error: 'forbidden', error_description: msg }
end end
# @todo something with ApplicationHelper#show_user # @todo something with ApplicationHelper#show_user

View file

@ -1,9 +1,7 @@
class Api::V1::ConfigsController < Api::V1::BaseController class Api::V1::ConfigsController < Api::V1::BaseController
before_action -> { doorkeeper_authorize! 'config:user', 'config:read', 'config:write' }
before_action ->{ doorkeeper_authorize! 'config:user', 'config:read', 'config:write' }
def show def show
render json: FoodsoftConfig, serializer: ConfigSerializer, root: 'config' render json: FoodsoftConfig, serializer: ConfigSerializer, root: 'config'
end end
end end

View file

@ -22,5 +22,4 @@ class Api::V1::FinancialTransactionClassesController < Api::V1::BaseController
def scope def scope
FinancialTransactionClass.all FinancialTransactionClass.all
end end
end end

View file

@ -22,5 +22,4 @@ class Api::V1::FinancialTransactionTypesController < Api::V1::BaseController
def scope def scope
FinancialTransactionType.includes(:bank_account, :financial_transaction_class) FinancialTransactionType.includes(:bank_account, :financial_transaction_class)
end end
end end

View file

@ -1,7 +1,7 @@
class Api::V1::FinancialTransactionsController < Api::V1::BaseController class Api::V1::FinancialTransactionsController < Api::V1::BaseController
include Concerns::CollectionScope include Concerns::CollectionScope
before_action ->{ doorkeeper_authorize! 'finance:read', 'finance:write' } before_action -> { doorkeeper_authorize! 'finance:read', 'finance:write' }
def index def index
render_collection search_scope render_collection search_scope
@ -20,5 +20,4 @@ class Api::V1::FinancialTransactionsController < Api::V1::BaseController
def ransack_auth_object def ransack_auth_object
:finance :finance
end end
end end

View file

@ -1,5 +1,4 @@
class Api::V1::NavigationsController < Api::V1::BaseController class Api::V1::NavigationsController < Api::V1::BaseController
def show def show
# we don't use active_model_serializers here, because source is a Hash # we don't use active_model_serializers here, because source is a Hash
render json: { navigation: transform(navigation) } render json: { navigation: transform(navigation) }
@ -20,5 +19,4 @@ class Api::V1::NavigationsController < Api::V1::BaseController
r r
end end
end end
end end

View file

@ -1,7 +1,7 @@
class Api::V1::OrderArticlesController < Api::V1::BaseController class Api::V1::OrderArticlesController < Api::V1::BaseController
include Concerns::CollectionScope include Concerns::CollectionScope
before_action ->{ doorkeeper_authorize! 'orders:read', 'orders:write' } before_action -> { doorkeeper_authorize! 'orders:read', 'orders:write' }
def index def index
render_collection search_scope render_collection search_scope

View file

@ -1,7 +1,7 @@
class Api::V1::OrdersController < Api::V1::BaseController class Api::V1::OrdersController < Api::V1::BaseController
include Concerns::CollectionScope include Concerns::CollectionScope
before_action ->{ doorkeeper_authorize! 'orders:read', 'orders:write' } before_action -> { doorkeeper_authorize! 'orders:read', 'orders:write' }
def index def index
render_collection search_scope render_collection search_scope

View file

@ -1,7 +1,7 @@
class Api::V1::User::FinancialTransactionsController < Api::V1::BaseController class Api::V1::User::FinancialTransactionsController < Api::V1::BaseController
include Concerns::CollectionScope include Concerns::CollectionScope
before_action ->{ doorkeeper_authorize! 'finance:user' } before_action -> { doorkeeper_authorize! 'finance:user' }
before_action :require_ordergroup before_action :require_ordergroup
before_action :require_minimum_balance, only: [:create] before_action :require_minimum_balance, only: [:create]
before_action -> { require_config_enabled :use_self_service }, only: [:create] before_action -> { require_config_enabled :use_self_service }, only: [:create]
@ -29,5 +29,4 @@ class Api::V1::User::FinancialTransactionsController < Api::V1::BaseController
def create_params def create_params
params.require(:financial_transaction).permit(:amount, :financial_transaction_type_id, :note) params.require(:financial_transaction).permit(:amount, :financial_transaction_type_id, :note)
end end
end end

View file

@ -1,7 +1,7 @@
class Api::V1::User::GroupOrderArticlesController < Api::V1::BaseController class Api::V1::User::GroupOrderArticlesController < Api::V1::BaseController
include Concerns::CollectionScope include Concerns::CollectionScope
before_action ->{ doorkeeper_authorize! 'group_orders:user' } before_action -> { doorkeeper_authorize! 'group_orders:user' }
before_action :require_ordergroup before_action :require_ordergroup
before_action :require_minimum_balance, only: [:create, :update] # destroy is ok before_action :require_minimum_balance, only: [:create, :update] # destroy is ok
@ -62,10 +62,10 @@ class Api::V1::User::GroupOrderArticlesController < Api::V1::BaseController
end end
def scope def scope
GroupOrderArticle. GroupOrderArticle
joins(:group_order). .joins(:group_order)
includes(order_article: :article, group_order: :order). .includes(order_article: :article, group_order: :order)
where(group_orders: { ordergroup_id: current_ordergroup.id }) .where(group_orders: { ordergroup_id: current_ordergroup.id })
end end
def scope_for_update def scope_for_update

View file

@ -1,6 +1,5 @@
class Api::V1::User::OrdergroupController < Api::V1::BaseController class Api::V1::User::OrdergroupController < Api::V1::BaseController
before_action -> { doorkeeper_authorize! 'finance:user' }, only: [:financial_overview]
before_action ->{ doorkeeper_authorize! 'finance:user' }, only: [:financial_overview]
def financial_overview def financial_overview
ordergroup = Ordergroup.include_transaction_class_sum.find(current_ordergroup.id) ordergroup = Ordergroup.include_transaction_class_sum.find(current_ordergroup.id)
@ -19,5 +18,4 @@ class Api::V1::User::OrdergroupController < Api::V1::BaseController
} }
} }
end end
end end

View file

@ -1,9 +1,7 @@
class Api::V1::User::UsersController < Api::V1::BaseController class Api::V1::User::UsersController < Api::V1::BaseController
before_action -> { doorkeeper_authorize! 'user:read', 'user:write' }
before_action ->{ doorkeeper_authorize! 'user:read', 'user:write' }
def show def show
render json: current_user render json: current_user
end end
end end

View file

@ -1,4 +1,3 @@
# encoding: utf-8
class ApplicationController < ActionController::Base class ApplicationController < ActionController::Base
include Concerns::FoodcoopScope include Concerns::FoodcoopScope
include Concerns::Auth include Concerns::Auth
@ -8,11 +7,10 @@ class ApplicationController < ActionController::Base
helper_method :available_locales helper_method :available_locales
protect_from_forgery protect_from_forgery
before_action :authenticate, :set_user_last_activity, :store_controller, :items_per_page before_action :authenticate, :set_user_last_activity, :store_controller, :items_per_page
after_action :remove_controller after_action :remove_controller
around_action :set_time_zone, :set_currency around_action :set_time_zone, :set_currency
# Returns the controller handling the current request. # Returns the controller handling the current request.
def self.current def self.current
Thread.current[:application_controller] Thread.current[:application_controller]
@ -90,10 +88,9 @@ class ApplicationController < ActionController::Base
old_currency = ::I18n.t('number.currency.format.unit') old_currency = ::I18n.t('number.currency.format.unit')
new_currency = FoodsoftConfig[:currency_unit] || '' new_currency = FoodsoftConfig[:currency_unit] || ''
new_currency += "\u202f" if FoodsoftConfig[:currency_space] new_currency += "\u202f" if FoodsoftConfig[:currency_space]
::I18n.backend.store_translations(::I18n.locale, number: {currency: {format: {unit: new_currency}}}) ::I18n.backend.store_translations(::I18n.locale, number: { currency: { format: { unit: new_currency } } })
yield yield
ensure ensure
::I18n.backend.store_translations(::I18n.locale, number: {currency: {format: {unit: old_currency}}}) ::I18n.backend.store_translations(::I18n.locale, number: { currency: { format: { unit: old_currency } } })
end end
end end

View file

@ -1,5 +1,4 @@
class ArticleCategoriesController < ApplicationController class ArticleCategoriesController < ApplicationController
inherit_resources # Build default REST Actions via plugin inherit_resources # Build default REST Actions via plugin
before_action :authenticate_article_meta before_action :authenticate_article_meta
@ -23,5 +22,4 @@ class ArticleCategoriesController < ApplicationController
def collection def collection
@article_categories = ArticleCategory.order('name') @article_categories = ArticleCategory.order('name')
end end
end end

View file

@ -1,21 +1,20 @@
# encoding: utf-8
class ArticlesController < ApplicationController class ArticlesController < ApplicationController
before_action :authenticate_article_meta, :find_supplier before_action :authenticate_article_meta, :find_supplier
def index def index
if params['sort'] if params['sort']
sort = case params['sort'] sort = case params['sort']
when "name" then "articles.name" when "name" then "articles.name"
when "unit" then "articles.unit" when "unit" then "articles.unit"
when "article_category" then "article_categories.name" when "article_category" then "article_categories.name"
when "note" then "articles.note" when "note" then "articles.note"
when "availability" then "articles.availability" when "availability" then "articles.availability"
when "name_reverse" then "articles.name DESC" when "name_reverse" then "articles.name DESC"
when "unit_reverse" then "articles.unit DESC" when "unit_reverse" then "articles.unit DESC"
when "article_category_reverse" then "article_categories.name DESC" when "article_category_reverse" then "article_categories.name DESC"
when "note_reverse" then "articles.note DESC" when "note_reverse" then "articles.note DESC"
when "availability_reverse" then "articles.availability DESC" when "availability_reverse" then "articles.availability DESC"
end end
else else
sort = "article_categories.name, articles.name" sort = "article_categories.name, articles.name"
end end
@ -99,7 +98,7 @@ class ArticlesController < ApplicationController
end end
end end
raise ActiveRecord::Rollback if invalid_articles # Rollback all changes raise ActiveRecord::Rollback if invalid_articles # Rollback all changes
end end
end end
end end
@ -117,25 +116,25 @@ class ArticlesController < ApplicationController
# makes different actions on selected articles # makes different actions on selected articles
def update_selected def update_selected
raise I18n.t('articles.controller.error_nosel') if params[:selected_articles].nil? raise I18n.t('articles.controller.error_nosel') if params[:selected_articles].nil?
articles = Article.find(params[:selected_articles]) articles = Article.find(params[:selected_articles])
Article.transaction do Article.transaction do
case params[:selected_action] case params[:selected_action]
when 'destroy' when 'destroy'
articles.each(&:mark_as_deleted) articles.each(&:mark_as_deleted)
flash[:notice] = I18n.t('articles.controller.update_sel.notice_destroy') flash[:notice] = I18n.t('articles.controller.update_sel.notice_destroy')
when 'setNotAvailable' when 'setNotAvailable'
articles.each {|a| a.update_attribute(:availability, false) } articles.each { |a| a.update_attribute(:availability, false) }
flash[:notice] = I18n.t('articles.controller.update_sel.notice_unavail') flash[:notice] = I18n.t('articles.controller.update_sel.notice_unavail')
when 'setAvailable' when 'setAvailable'
articles.each {|a| a.update_attribute(:availability, true) } articles.each { |a| a.update_attribute(:availability, true) }
flash[:notice] = I18n.t('articles.controller.update_sel.notice_avail') flash[:notice] = I18n.t('articles.controller.update_sel.notice_avail')
else else
flash[:alert] = I18n.t('articles.controller.update_sel.notice_noaction') flash[:alert] = I18n.t('articles.controller.update_sel.notice_noaction')
end end
end end
# action succeded # action succeded
redirect_to supplier_articles_url(@supplier, :per_page => params[:per_page]) redirect_to supplier_articles_url(@supplier, :per_page => params[:per_page])
rescue => error rescue => error
redirect_to supplier_articles_url(@supplier, :per_page => params[:per_page]), redirect_to supplier_articles_url(@supplier, :per_page => params[:per_page]),
:alert => I18n.t('errors.general_msg', :msg => error) :alert => I18n.t('errors.general_msg', :msg => error)
@ -149,7 +148,7 @@ class ArticlesController < ApplicationController
# Update articles from a spreadsheet # Update articles from a spreadsheet
def parse_upload def parse_upload
uploaded_file = params[:articles]['file'] or raise I18n.t('articles.controller.parse_upload.no_file') uploaded_file = params[:articles]['file'] or raise I18n.t('articles.controller.parse_upload.no_file')
options = {filename: uploaded_file.original_filename} options = { filename: uploaded_file.original_filename }
options[:outlist_absent] = (params[:articles]['outlist_absent'] == '1') options[:outlist_absent] = (params[:articles]['outlist_absent'] == '1')
options[:convert_units] = (params[:articles]['convert_units'] == '1') options[:convert_units] = (params[:articles]['convert_units'] == '1')
@updated_article_pairs, @outlisted_articles, @new_articles = @supplier.sync_from_file uploaded_file.tempfile, options @updated_article_pairs, @outlisted_articles, @new_articles = @supplier.sync_from_file uploaded_file.tempfile, options
@ -177,10 +176,10 @@ class ArticlesController < ApplicationController
# Updates, deletes articles when upload or sync form is submitted # Updates, deletes articles when upload or sync form is submitted
def update_synchronized def update_synchronized
@outlisted_articles = Article.find(params[:outlisted_articles].try(:keys)||[]) @outlisted_articles = Article.find(params[:outlisted_articles].try(:keys) || [])
@updated_articles = Article.find(params[:articles].try(:keys)||[]) @updated_articles = Article.find(params[:articles].try(:keys) || [])
@updated_articles.map{|a| a.assign_attributes(params[:articles][a.id.to_s]) } @updated_articles.map { |a| a.assign_attributes(params[:articles][a.id.to_s]) }
@new_articles = (params[:new_articles]||[]).map{|a| @supplier.articles.build(a) } @new_articles = (params[:new_articles] || []).map { |a| @supplier.articles.build(a) }
has_error = false has_error = false
Article.transaction do Article.transaction do
@ -192,9 +191,9 @@ class ArticlesController < ApplicationController
has_error = true has_error = true
end end
# Update articles # Update articles
@updated_articles.each {|a| a.save or has_error=true } @updated_articles.each { |a| a.save or has_error = true }
# Add new articles # Add new articles
@new_articles.each {|a| a.save or has_error=true } @new_articles.each { |a| a.save or has_error = true }
raise ActiveRecord::Rollback if has_error raise ActiveRecord::Rollback if has_error
end end

View file

@ -24,7 +24,7 @@ module Concerns::Auth
def login(user) def login(user)
session[:user_id] = user.id session[:user_id] = user.id
session[:scope] = FoodsoftConfig.scope # Save scope in session to not allow switching between foodcoops with one account session[:scope] = FoodsoftConfig.scope # Save scope in session to not allow switching between foodcoops with one account
session[:locale] = user.locale session[:locale] = user.locale
end end
@ -56,18 +56,18 @@ module Concerns::Auth
# We have an authenticated user, now check role... # We have an authenticated user, now check role...
# Roles gets the user through his memberships. # Roles gets the user through his memberships.
hasRole = case role hasRole = case role
when 'admin' then current_user.role_admin? when 'admin' then current_user.role_admin?
when 'finance' then current_user.role_finance? when 'finance' then current_user.role_finance?
when 'article_meta' then current_user.role_article_meta? when 'article_meta' then current_user.role_article_meta?
when 'pickups' then current_user.role_pickups? when 'pickups' then current_user.role_pickups?
when 'suppliers' then current_user.role_suppliers? when 'suppliers' then current_user.role_suppliers?
when 'orders' then current_user.role_orders? when 'orders' then current_user.role_orders?
when 'finance_or_invoices' then (current_user.role_finance? || current_user.role_invoices?) when 'finance_or_invoices' then (current_user.role_finance? || current_user.role_invoices?)
when 'finance_or_orders' then (current_user.role_finance? || current_user.role_orders?) when 'finance_or_orders' then (current_user.role_finance? || current_user.role_orders?)
when 'pickups_or_orders' then (current_user.role_pickups? || current_user.role_orders?) when 'pickups_or_orders' then (current_user.role_pickups? || current_user.role_orders?)
when 'any' then true # no role required when 'any' then true # no role required
else false # any unknown role will always fail else false # any unknown role will always fail
end end
if hasRole if hasRole
current_user current_user
else else
@ -137,6 +137,7 @@ module Concerns::Auth
# @see https://github.com/doorkeeper-gem/doorkeeper/issues/71#issuecomment-5471317 # @see https://github.com/doorkeeper-gem/doorkeeper/issues/71#issuecomment-5471317
def expire_access_tokens def expire_access_tokens
return unless @current_user return unless @current_user
Doorkeeper::AccessToken.transaction do Doorkeeper::AccessToken.transaction do
token_scope = Doorkeeper::AccessToken.where(revoked_at: nil, resource_owner_id: @current_user.id) token_scope = Doorkeeper::AccessToken.where(revoked_at: nil, resource_owner_id: @current_user.id)
token_scope.each do |token| token_scope.each do |token|
@ -146,8 +147,7 @@ module Concerns::Auth
end end
# Redirect to the login page, used in authenticate, plugins can override this. # Redirect to the login page, used in authenticate, plugins can override this.
def redirect_to_login(options={}) def redirect_to_login(options = {})
redirect_to login_url, options redirect_to login_url, options
end end
end end

View file

@ -36,7 +36,7 @@ module Concerns::AuthApi
# Make sure that at least one the given OAuth scopes is valid for the current user's permissions. # Make sure that at least one the given OAuth scopes is valid for the current user's permissions.
# @raise Api::Errors::PermissionsRequired # @raise Api::Errors::PermissionsRequired
def doorkeeper_authorize_roles!(*scopes) def doorkeeper_authorize_roles!(*scopes)
unless scopes.any? {|scope| doorkeeper_scope_permitted?(scope) } unless scopes.any? { |scope| doorkeeper_scope_permitted?(scope) }
raise Api::Errors::PermissionRequired.new('Forbidden, no permission') raise Api::Errors::PermissionRequired.new('Forbidden, no permission')
end end
end end
@ -60,7 +60,7 @@ module Concerns::AuthApi
when 'suppliers' then return current_user.role_suppliers? when 'suppliers' then return current_user.role_suppliers?
when 'group_orders' then return current_user.role_orders? when 'group_orders' then return current_user.role_orders?
when 'finance' then return current_user.role_finance? when 'finance' then return current_user.role_finance?
# please note that offline_access does not belong here, since it is not used for permission checking # please note that offline_access does not belong here, since it is not used for permission checking
end end
case scope case scope

View file

@ -54,5 +54,4 @@ module Concerns::CollectionScope
def ransack_auth_object def ransack_auth_object
nil nil
end end
end end

View file

@ -30,7 +30,6 @@ module Concerns::FoodcoopScope
# Always stay in foodcoop url scope # Always stay in foodcoop url scope
def default_url_options(options = {}) def default_url_options(options = {})
super().merge({foodcoop: FoodsoftConfig.scope}) super().merge({ foodcoop: FoodsoftConfig.scope })
end end
end end

View file

@ -47,5 +47,4 @@ module Concerns::Locale
locale = session[:locale] = ::I18n.locale locale = session[:locale] = ::I18n.locale
logger.info("Set locale to #{locale}") logger.info("Set locale to #{locale}")
end end
end end

View file

@ -9,9 +9,8 @@ module Concerns::SendOrderPdf
when 'articles' then OrderByArticles when 'articles' then OrderByArticles
when 'fax' then OrderFax when 'fax' then OrderFax
when 'matrix' then OrderMatrix when 'matrix' then OrderMatrix
end end
pdf = klass.new order pdf = klass.new order
send_data pdf.to_pdf, filename: pdf.filename, type: 'application/pdf' send_data pdf.to_pdf, filename: pdf.filename, type: 'application/pdf'
end end
end end

View file

@ -1,6 +1,4 @@
# encoding: utf-8
class DeliveriesController < ApplicationController class DeliveriesController < ApplicationController
before_action :find_supplier, :exclude => :fill_new_stock_article_form before_action :find_supplier, :exclude => :fill_new_stock_article_form
def index def index
@ -14,7 +12,7 @@ class DeliveriesController < ApplicationController
def new def new
@delivery = @supplier.deliveries.build @delivery = @supplier.deliveries.build
@delivery.date = Date.today #TODO: move to model/database @delivery.date = Date.today # TODO: move to model/database
end end
def create def create
@ -37,7 +35,7 @@ class DeliveriesController < ApplicationController
if @delivery.update_attributes(params[:delivery]) if @delivery.update_attributes(params[:delivery])
flash[:notice] = I18n.t('deliveries.update.notice') flash[:notice] = I18n.t('deliveries.update.notice')
redirect_to [@supplier,@delivery] redirect_to [@supplier, @delivery]
else else
render :action => "edit" render :action => "edit"
end end
@ -68,5 +66,4 @@ class DeliveriesController < ApplicationController
render :layout => false render :layout => false
end end
end end

View file

@ -1,5 +1,4 @@
class FeedbackController < ApplicationController class FeedbackController < ApplicationController
def new def new
end end
@ -11,5 +10,4 @@ class FeedbackController < ApplicationController
render :action => 'new' render :action => 'new'
end end
end end
end end

View file

@ -1,6 +1,4 @@
# encoding: utf-8
class Finance::BalancingController < Finance::BaseController class Finance::BalancingController < Finance::BaseController
def index def index
@orders = Order.finished.page(params[:page]).per(@per_page).order('ends DESC') @orders = Order.finished.page(params[:page]).per(@per_page).order('ends DESC')
end end
@ -11,20 +9,20 @@ class Finance::BalancingController < Finance::BaseController
@comments = @order.comments @comments = @order.comments
@articles = @order.order_articles.ordered_or_member.includes(:article, :article_price, @articles = @order.order_articles.ordered_or_member.includes(:article, :article_price,
group_order_articles: {group_order: :ordergroup}) group_order_articles: { group_order: :ordergroup })
sort_param = params['sort'] || 'name' sort_param = params['sort'] || 'name'
@articles = case sort_param @articles = case sort_param
when 'name' then when 'name' then
@articles.order('articles.name ASC') @articles.order('articles.name ASC')
when 'name_reverse' then when 'name_reverse' then
@articles.order('articles.name DESC') @articles.order('articles.name DESC')
when 'order_number' then when 'order_number' then
@articles.order('articles.order_number ASC') @articles.order('articles.order_number ASC')
when 'order_number_reverse' then when 'order_number_reverse' then
@articles.order('articles.order_number DESC') @articles.order('articles.order_number DESC')
else else
@articles @articles
end end
render layout: false if request.xhr? render layout: false if request.xhr?
@ -84,7 +82,6 @@ class Finance::BalancingController < Finance::BaseController
@type = FinancialTransactionType.find_by_id(params.permit(:type)[:type]) @type = FinancialTransactionType.find_by_id(params.permit(:type)[:type])
@order.close!(@current_user, @type) @order.close!(@current_user, @type)
redirect_to finance_order_index_url, notice: t('finance.balancing.close.notice') redirect_to finance_order_index_url, notice: t('finance.balancing.close.notice')
rescue => error rescue => error
redirect_to new_finance_order_url(order_id: @order.id), alert: t('finance.balancing.close.alert', message: error.message) redirect_to new_finance_order_url(order_id: @order.id), alert: t('finance.balancing.close.alert', message: error.message)
end end
@ -110,5 +107,4 @@ class Finance::BalancingController < Finance::BaseController
rescue => error rescue => error
redirect_to finance_order_index_url, alert: t('errors.general_msg', msg: error.message) redirect_to finance_order_index_url, alert: t('errors.general_msg', msg: error.message)
end end
end end

View file

@ -1,5 +1,4 @@
class Finance::BankAccountsController < Finance::BaseController class Finance::BankAccountsController < Finance::BaseController
def index def index
@bank_accounts = BankAccount.order('name') @bank_accounts = BankAccount.order('name')
redirect_to finance_bank_account_transactions_url(@bank_accounts.first) if @bank_accounts.count == 1 redirect_to finance_bank_account_transactions_url(@bank_accounts.first) if @bank_accounts.count == 1
@ -26,7 +25,7 @@ class Finance::BankAccountsController < Finance::BaseController
flash.notice = t('.notice', count: importer.count) if ok flash.notice = t('.notice', count: importer.count) if ok
@auto_submit = importer.auto_submit @auto_submit = importer.auto_submit
@controls = importer.controls @controls = importer.controls
#TODO: encrypt state # TODO: encrypt state
@state = YAML.dump importer.dump @state = YAML.dump importer.dump
else else
ok = true ok = true
@ -39,6 +38,7 @@ class Finance::BankAccountsController < Finance::BaseController
needs_redirect = true needs_redirect = true
ensure ensure
return unless needs_redirect return unless needs_redirect
redirect_path = finance_bank_account_transactions_url(@bank_account) redirect_path = finance_bank_account_transactions_url(@bank_account)
if request.post? if request.post?
@js_redirect = redirect_path @js_redirect = redirect_path
@ -46,5 +46,4 @@ class Finance::BankAccountsController < Finance::BaseController
redirect_to redirect_path redirect_to redirect_path
end end
end end
end end

View file

@ -5,12 +5,12 @@ class Finance::BankTransactionsController < ApplicationController
def index def index
if params["sort"] if params["sort"]
sort = case params["sort"] sort = case params["sort"]
when "date" then "date" when "date" then "date"
when "amount" then "amount" when "amount" then "amount"
when "financial_link" then "financial_link_id" when "financial_link" then "financial_link_id"
when "date_reverse" then "date DESC" when "date_reverse" then "date DESC"
when "amount_reverse" then "amount DESC" when "amount_reverse" then "amount DESC"
when "financial_link_reverse" then "financial_link_id DESC" when "financial_link_reverse" then "financial_link_id DESC"
end end
else else
sort = "date DESC" sort = "date DESC"

View file

@ -110,13 +110,13 @@ class Finance::FinancialLinksController < Finance::BaseController
redirect_to finance_link_url(@financial_link), notice: t('.notice') redirect_to finance_link_url(@financial_link), notice: t('.notice')
end end
protected protected
def find_financial_link def find_financial_link
@financial_link = FinancialLink.find(params[:id]) @financial_link = FinancialLink.find(params[:id])
end end
private private
def financial_transaction_params def financial_transaction_params
params.require(:financial_transaction).permit(:financial_transaction_type_id, :ordergroup_id, :amount, :note) params.require(:financial_transaction).permit(:financial_transaction_type_id, :ordergroup_id, :amount, :note)
@ -128,5 +128,4 @@ private
JOIN bank_transactions b ON a.iban = b.iban AND b.financial_link_id = #{financial_link_id.to_i} JOIN bank_transactions b ON a.iban = b.iban AND b.financial_link_id = #{financial_link_id.to_i}
SQL SQL
end end
end end

View file

@ -1,20 +1,19 @@
# encoding: utf-8
class Finance::FinancialTransactionsController < ApplicationController class Finance::FinancialTransactionsController < ApplicationController
before_action :authenticate_finance before_action :authenticate_finance
before_action :find_ordergroup, :except => [:new_collection, :create_collection, :index_collection] before_action :find_ordergroup, :except => [:new_collection, :create_collection, :index_collection]
inherit_resources inherit_resources
# belongs_to :ordergroup # belongs_to :ordergroup
def index def index
if params['sort'] if params['sort']
sort = case params['sort'] sort = case params['sort']
when "date" then "created_on" when "date" then "created_on"
when "note" then "note" when "note" then "note"
when "amount" then "amount" when "amount" then "amount"
when "date_reverse" then "created_on DESC" when "date_reverse" then "created_on DESC"
when "note_reverse" then "note DESC" when "note_reverse" then "note DESC"
when "amount_reverse" then "amount DESC" when "amount_reverse" then "amount DESC"
end end
else else
sort = "created_on DESC" sort = "created_on DESC"
end end
@ -79,6 +78,7 @@ class Finance::FinancialTransactionsController < ApplicationController
def create_collection def create_collection
raise I18n.t('finance.financial_transactions.controller.create_collection.error_note_required') if params[:note].blank? raise I18n.t('finance.financial_transactions.controller.create_collection.error_note_required') if params[:note].blank?
type = FinancialTransactionType.find_by_id(params[:type_id]) type = FinancialTransactionType.find_by_id(params[:type_id])
financial_link = nil financial_link = nil
@ -103,12 +103,12 @@ class Finance::FinancialTransactionsController < ApplicationController
if params[:create_foodcoop_transaction] if params[:create_foodcoop_transaction]
ft = FinancialTransaction.new({ ft = FinancialTransaction.new({
financial_transaction_type: type, financial_transaction_type: type,
user: @current_user, user: @current_user,
amount: foodcoop_amount, amount: foodcoop_amount,
note: params[:note], note: params[:note],
financial_link: financial_link, financial_link: financial_link,
}) })
ft.save! ft.save!
end end
@ -131,5 +131,4 @@ class Finance::FinancialTransactionsController < ApplicationController
@foodcoop = true @foodcoop = true
end end
end end
end end

View file

@ -1,5 +1,4 @@
class Finance::OrdergroupsController < Finance::BaseController class Finance::OrdergroupsController < Finance::BaseController
def index def index
m = /^(?<col>name|sum_of_class_\d+)(?<reverse>_reverse)?$/.match params["sort"] m = /^(?<col>name|sum_of_class_\d+)(?<reverse>_reverse)?$/.match params["sort"]
if m if m

View file

@ -1,5 +1,4 @@
class Foodcoop::OrdergroupsController < ApplicationController class Foodcoop::OrdergroupsController < ApplicationController
def index def index
@ordergroups = Ordergroup.undeleted.order('name') @ordergroups = Ordergroup.undeleted.order('name')

View file

@ -1,5 +1,4 @@
class Foodcoop::UsersController < ApplicationController class Foodcoop::UsersController < ApplicationController
def index def index
@users = User.undeleted.natural_order @users = User.undeleted.natural_order
@ -17,5 +16,4 @@ class Foodcoop::UsersController < ApplicationController
format.js { render :layout => false } # index.js.erb format.js { render :layout => false } # index.js.erb
end end
end end
end end

View file

@ -1,16 +1,15 @@
class Foodcoop::WorkgroupsController < ApplicationController class Foodcoop::WorkgroupsController < ApplicationController
before_action :authenticate_membership_or_admin, before_action :authenticate_membership_or_admin,
:except => [:index] :except => [:index]
def index def index
@workgroups = Workgroup.order("name") @workgroups = Workgroup.order("name")
end end
def edit def edit
@workgroup = Workgroup.find(params[:id]) @workgroup = Workgroup.find(params[:id])
end end
def update def update
@workgroup = Workgroup.find(params[:id]) @workgroup = Workgroup.find(params[:id])
if @workgroup.update_attributes(params[:workgroup]) if @workgroup.update_attributes(params[:workgroup])

View file

@ -1,5 +1,4 @@
class GroupOrderArticlesController < ApplicationController class GroupOrderArticlesController < ApplicationController
before_action :authenticate_finance before_action :authenticate_finance
before_action :find_group_order_article, except: [:new, :create] before_action :find_group_order_article, except: [:new, :create]
@ -30,7 +29,7 @@ class GroupOrderArticlesController < ApplicationController
update_summaries(@group_order_article) update_summaries(@group_order_article)
render :create render :create
else # Validation failed, show form else # Validation failed, show form
render :new render :new
end end
end end
@ -50,7 +49,7 @@ class GroupOrderArticlesController < ApplicationController
def destroy def destroy
# only destroy if quantity and tolerance was zero already, so that we don't # only destroy if quantity and tolerance was zero already, so that we don't
# lose what the user ordered, if any # lose what the user ordered, if any
if @group_order_article.quantity > 0 || @group_order_article.tolerance >0 if @group_order_article.quantity > 0 || @group_order_article.tolerance > 0
@group_order_article.update_attribute(:result, 0) @group_order_article.update_attribute(:result, 0)
else else
@group_order_article.destroy @group_order_article.destroy

View file

@ -33,7 +33,7 @@ class GroupOrdersController < ApplicationController
end end
def show def show
@order= @group_order.order @order = @group_order.order
end end
def edit def edit
@ -100,12 +100,11 @@ class GroupOrdersController < ApplicationController
if @ordergroup.not_enough_apples? if @ordergroup.not_enough_apples?
redirect_to group_orders_url, redirect_to group_orders_url,
alert: t('not_enough_apples', scope: 'group_orders.messages', apples: @ordergroup.apples, alert: t('not_enough_apples', scope: 'group_orders.messages', apples: @ordergroup.apples,
stop_ordering_under: FoodsoftConfig[:stop_ordering_under]) stop_ordering_under: FoodsoftConfig[:stop_ordering_under])
end end
end end
def order_id_param def order_id_param
params[:order_id] || (params[:group_order] && params[:group_order][:order_id]) params[:order_id] || (params[:group_order] && params[:group_order][:order_id])
end end
end end

View file

@ -1,6 +1,4 @@
# encoding: utf-8
class HomeController < ApplicationController class HomeController < ApplicationController
def index def index
# unaccepted tasks # unaccepted tasks
@unaccepted_tasks = Task.order(:due_date).unaccepted_tasks_for(current_user) @unaccepted_tasks = Task.order(:due_date).unaccepted_tasks_for(current_user)
@ -44,13 +42,13 @@ class HomeController < ApplicationController
if params['sort'] if params['sort']
sort = case params['sort'] sort = case params['sort']
when "date" then "created_on" when "date" then "created_on"
when "note" then "note" when "note" then "note"
when "amount" then "amount" when "amount" then "amount"
when "date_reverse" then "created_on DESC" when "date_reverse" then "created_on DESC"
when "note_reverse" then "note DESC" when "note_reverse" then "note DESC"
when "amount_reverse" then "amount DESC" when "amount_reverse" then "amount DESC"
end end
else else
sort = "created_on DESC" sort = "created_on DESC"
end end
@ -88,5 +86,4 @@ class HomeController < ApplicationController
params.require(:user).require(:ordergroup).permit(:contact_address) params.require(:user).require(:ordergroup).permit(:contact_address)
end end
end end
end end

View file

@ -1,12 +1,11 @@
class InvitesController < ApplicationController class InvitesController < ApplicationController
before_action :authenticate_membership_or_admin_for_invites before_action :authenticate_membership_or_admin_for_invites
before_action -> { require_config_disabled :disable_invite } before_action -> { require_config_disabled :disable_invite }
def new def new
@invite = Invite.new(:user => @current_user, :group => @group) @invite = Invite.new(:user => @current_user, :group => @group)
end end
def create def create
authenticate_membership_or_admin params[:invite][:group_id] authenticate_membership_or_admin params[:invite][:group_id]
@invite = Invite.new(params[:invite]) @invite = Invite.new(params[:invite])

View file

@ -1,13 +1,12 @@
# encoding: utf-8
class LoginController < ApplicationController class LoginController < ApplicationController
skip_before_action :authenticate # no authentication since this is the login page skip_before_action :authenticate # no authentication since this is the login page
before_action :validate_token, :only => [:new_password, :update_password] before_action :validate_token, :only => [:new_password, :update_password]
# Display the form to enter an email address requesting a token to set a new password. # Display the form to enter an email address requesting a token to set a new password.
def forgot_password def forgot_password
@user = User.new @user = User.new
end end
# Sends an email to a user with the token that allows setting a new password through action "password". # Sends an email to a user with the token that allows setting a new password through action "password".
def reset_password def reset_password
if request.get? || params[:user].nil? # Catch for get request and give better error message. if request.get? || params[:user].nil? # Catch for get request and give better error message.
@ -19,12 +18,12 @@ class LoginController < ApplicationController
end end
redirect_to login_url, :notice => I18n.t('login.controller.reset_password.notice') redirect_to login_url, :notice => I18n.t('login.controller.reset_password.notice')
end end
# Set a new password with a token from the password reminder email. # Set a new password with a token from the password reminder email.
# Called with params :id => User.id and :token => User.reset_password_token to specify a new password. # Called with params :id => User.id and :token => User.reset_password_token to specify a new password.
def new_password def new_password
end end
# Sets a new password. # Sets a new password.
# Called with params :id => User.id and :token => User.reset_password_token to specify a new password. # Called with params :id => User.id and :token => User.reset_password_token to specify a new password.
def update_password def update_password

View file

@ -1,5 +1,4 @@
class OrderCommentsController < ApplicationController class OrderCommentsController < ApplicationController
def new def new
@order = Order.find(params[:order_id]) @order = Order.find(params[:order_id])
@order_comment = @order.comments.build(:user => current_user) @order_comment = @order.comments.build(:user => current_user)

View file

@ -1,4 +1,3 @@
# encoding: utf-8
# #
# Controller for managing orders, i.e. all actions that require the "orders" role. # Controller for managing orders, i.e. all actions that require the "orders" role.
# Normal ordering actions of members of order groups is handled by the OrderingController. # Normal ordering actions of members of order groups is handled by the OrderingController.
@ -16,12 +15,12 @@ class OrdersController < ApplicationController
@per_page = 15 @per_page = 15
if params['sort'] if params['sort']
sort = case params['sort'] sort = case params['sort']
when "supplier" then "suppliers.name, ends DESC" when "supplier" then "suppliers.name, ends DESC"
when "pickup" then "pickup DESC" when "pickup" then "pickup DESC"
when "ends" then "ends DESC" when "ends" then "ends DESC"
when "supplier_reverse" then "suppliers.name DESC" when "supplier_reverse" then "suppliers.name DESC"
when "ends_reverse" then "ends" when "ends_reverse" then "ends"
end end
else else
sort = "ends DESC" sort = "ends DESC"
end end
@ -32,13 +31,13 @@ class OrdersController < ApplicationController
# Gives a view for the results to a specific order # Gives a view for the results to a specific order
# Renders also the pdf # Renders also the pdf
def show def show
@order= Order.find(params[:id]) @order = Order.find(params[:id])
@view = (params[:view] || 'default').gsub(/[^-_a-zA-Z0-9]/, '') @view = (params[:view] || 'default').gsub(/[^-_a-zA-Z0-9]/, '')
@partial = case @view @partial = case @view
when 'default' then 'articles' when 'default' then 'articles'
when 'groups' then 'shared/articles_by/groups' when 'groups' then 'shared/articles_by/groups'
when 'articles' then 'shared/articles_by/articles' when 'articles' then 'shared/articles_by/articles'
else 'articles' else 'articles'
end end
respond_to do |format| respond_to do |format|
@ -50,10 +49,10 @@ class OrdersController < ApplicationController
send_order_pdf @order, params[:document] send_order_pdf @order, params[:document]
end end
format.csv do format.csv do
send_data OrderCsv.new(@order).to_csv, filename: @order.name+'.csv', type: 'text/csv' send_data OrderCsv.new(@order).to_csv, filename: @order.name + '.csv', type: 'text/csv'
end end
format.text do format.text do
send_data OrderTxt.new(@order).to_txt, filename: @order.name+'.txt', type: 'text/plain' send_data OrderTxt.new(@order).to_txt, filename: @order.name + '.txt', type: 'text/plain'
end end
end end
end end
@ -163,6 +162,7 @@ class OrdersController < ApplicationController
def update_order_amounts def update_order_amounts
return if not params[:order_articles] return if not params[:order_articles]
# where to leave remainder during redistribution # where to leave remainder during redistribution
rest_to = [] rest_to = []
rest_to << :tolerance if params[:rest_to_tolerance] rest_to << :tolerance if params[:rest_to_tolerance]
@ -186,18 +186,19 @@ class OrdersController < ApplicationController
unless oa.units_received.blank? unless oa.units_received.blank?
cunits[0] += oa.units_received * oa.article.unit_quantity cunits[0] += oa.units_received * oa.article.unit_quantity
oacounts = oa.redistribute oa.units_received * oa.price.unit_quantity, rest_to oacounts = oa.redistribute oa.units_received * oa.price.unit_quantity, rest_to
oacounts.each_with_index {|c,i| cunits[i+1]+=c; counts[i+1]+=1 if c>0 } oacounts.each_with_index { |c, i| cunits[i + 1] += c; counts[i + 1] += 1 if c > 0 }
end end
end end
oa.save! oa.save!
end end
end end
return nil if counts[0] == 0 return nil if counts[0] == 0
notice = [] notice = []
notice << I18n.t('orders.update_order_amounts.msg1', count: counts[0], units: cunits[0]) notice << I18n.t('orders.update_order_amounts.msg1', count: counts[0], units: cunits[0])
notice << I18n.t('orders.update_order_amounts.msg2', count: counts[1], units: cunits[1]) if params[:rest_to_tolerance] notice << I18n.t('orders.update_order_amounts.msg2', count: counts[1], units: cunits[1]) if params[:rest_to_tolerance]
notice << I18n.t('orders.update_order_amounts.msg3', count: counts[2], units: cunits[2]) if params[:rest_to_stock] notice << I18n.t('orders.update_order_amounts.msg3', count: counts[2], units: cunits[2]) if params[:rest_to_stock]
if counts[3]>0 || cunits[3]>0 if counts[3] > 0 || cunits[3] > 0
notice << I18n.t('orders.update_order_amounts.msg4', count: counts[3], units: cunits[3]) notice << I18n.t('orders.update_order_amounts.msg4', count: counts[3], units: cunits[3])
end end
notice.join(', ') notice.join(', ')
@ -206,5 +207,4 @@ class OrdersController < ApplicationController
def remove_empty_article def remove_empty_article
params[:order][:article_ids].reject!(&:blank?) if params[:order] && params[:order][:article_ids] params[:order][:article_ids].reject!(&:blank?) if params[:order] && params[:order][:article_ids]
end end
end end

View file

@ -1,5 +1,4 @@
class PickupsController < ApplicationController class PickupsController < ApplicationController
before_action :authenticate_pickups before_action :authenticate_pickups
def index def index

View file

@ -1,5 +1,4 @@
class SessionsController < ApplicationController class SessionsController < ApplicationController
skip_before_action :authenticate skip_before_action :authenticate
layout 'login' layout 'login'
@ -30,5 +29,4 @@ class SessionsController < ApplicationController
def redirect_to_foodcoop def redirect_to_foodcoop
redirect_to root_path redirect_to root_path
end end
end end

View file

@ -1,8 +1,7 @@
class StockitController < ApplicationController class StockitController < ApplicationController
def index def index
@stock_articles = StockArticle.undeleted.includes(:supplier, :article_category). @stock_articles = StockArticle.undeleted.includes(:supplier, :article_category)
order('suppliers.name, article_categories.name, articles.name') .order('suppliers.name, article_categories.name, articles.name')
end end
def index_on_stock_article_create # See publish/subscribe design pattern in /doc. def index_on_stock_article_create # See publish/subscribe design pattern in /doc.
@ -40,7 +39,7 @@ class StockitController < ApplicationController
end end
def create def create
@stock_article = StockArticle.new({quantity: 0}.merge(params[:stock_article])) @stock_article = StockArticle.new({ quantity: 0 }.merge(params[:stock_article]))
@stock_article.save! @stock_article.save!
render :layout => false render :layout => false
rescue ActiveRecord::RecordInvalid rescue ActiveRecord::RecordInvalid
@ -78,10 +77,10 @@ class StockitController < ApplicationController
render :layout => false render :layout => false
rescue => error rescue => error
render :partial => "destroy_fail", :layout => false, render :partial => "destroy_fail", :layout => false,
:locals => { :fail_msg => I18n.t('errors.general_msg', :msg => error.message) } :locals => { :fail_msg => I18n.t('errors.general_msg', :msg => error.message) }
end end
#TODO: Fix this!! # TODO: Fix this!!
def articles_search def articles_search
@articles = Article.not_in_stock.limit(8).where('name LIKE ?', "%#{params[:term]}%") @articles = Article.not_in_stock.limit(8).where('name LIKE ?', "%#{params[:term]}%")
render :json => @articles.map(&:name) render :json => @articles.map(&:name)

View file

@ -11,7 +11,7 @@ class StylesController < ApplicationController
if css.blank? if css.blank?
render body: nil, content_type: 'text/css', status: 404 render body: nil, content_type: 'text/css', status: 404
else else
expires_in 1.week, public:true if params[:md5].present? expires_in 1.week, public: true if params[:md5].present?
render body: css, content_type: 'text/css' render body: css, content_type: 'text/css'
end end
end end

View file

@ -1,4 +1,3 @@
# encoding: utf-8
class SuppliersController < ApplicationController class SuppliersController < ApplicationController
before_action :authenticate_suppliers, :except => [:index, :list] before_action :authenticate_suppliers, :except => [:index, :list]
helper :deliveries helper :deliveries
@ -18,7 +17,7 @@ class SuppliersController < ApplicationController
# if shared_supplier_id is given, the new supplier will filled whith its attributes # if shared_supplier_id is given, the new supplier will filled whith its attributes
def new def new
if params[:shared_supplier_id] if params[:shared_supplier_id]
shared_supplier = SharedSupplier.find(params[:shared_supplier_id]) shared_supplier = SharedSupplier.find(params[:shared_supplier_id])
@supplier = shared_supplier.suppliers.new(shared_supplier.autofill_attributes) @supplier = shared_supplier.suppliers.new(shared_supplier.autofill_attributes)
else else
@supplier = Supplier.new @supplier = Supplier.new
@ -55,9 +54,9 @@ class SuppliersController < ApplicationController
@supplier.mark_as_deleted @supplier.mark_as_deleted
flash[:notice] = I18n.t('suppliers.destroy.notice') flash[:notice] = I18n.t('suppliers.destroy.notice')
redirect_to suppliers_path redirect_to suppliers_path
rescue => e rescue => e
flash[:error] = I18n.t('errors.general_msg', :msg => e.message) flash[:error] = I18n.t('errors.general_msg', :msg => e.message)
redirect_to @supplier redirect_to @supplier
end end
# gives a list with all available shared_suppliers # gives a list with all available shared_suppliers
@ -74,5 +73,4 @@ class SuppliersController < ApplicationController
:iban, :custom_fields, :delivery_days, :order_howto, :note, :supplier_category_id, :iban, :custom_fields, :delivery_days, :order_howto, :note, :supplier_category_id,
:shared_supplier_id, :min_order_quantity, :shared_sync_method) :shared_supplier_id, :min_order_quantity, :shared_sync_method)
end end
end end

View file

@ -1,10 +1,9 @@
# encoding: utf-8
class TasksController < ApplicationController class TasksController < ApplicationController
#auto_complete_for :user, :nick # auto_complete_for :user, :nick
def index def index
@non_group_tasks = Task.non_group.order('due_date', 'name').includes(assignments: :user) @non_group_tasks = Task.non_group.order('due_date', 'name').includes(assignments: :user)
@groups = Workgroup.order(:name).includes(open_tasks: {assignments: :user}) @groups = Workgroup.order(:name).includes(open_tasks: { assignments: :user })
end end
def user def user
@ -19,7 +18,7 @@ class TasksController < ApplicationController
def create def create
@task = Task.new(current_user_id: current_user.id) @task = Task.new(current_user_id: current_user.id)
@task.created_by = current_user @task.created_by = current_user
@task.attributes=(task_params) @task.attributes = (task_params)
if params[:periodic] if params[:periodic]
@task.periodic_task_group = PeriodicTaskGroup.new @task.periodic_task_group = PeriodicTaskGroup.new
end end
@ -47,7 +46,7 @@ class TasksController < ApplicationController
was_periodic = @task.periodic? was_periodic = @task.periodic?
prev_due_date = @task.due_date prev_due_date = @task.due_date
@task.current_user_id = current_user.id @task.current_user_id = current_user.id
@task.attributes=(task_params) @task.attributes = (task_params)
if @task.errors.empty? && @task.save if @task.errors.empty? && @task.save
task_group.update_tasks_including(@task, prev_due_date) if params[:periodic] task_group.update_tasks_including(@task, prev_due_date) if params[:periodic]
flash[:notice] = I18n.t('tasks.update.notice') flash[:notice] = I18n.t('tasks.update.notice')
@ -122,5 +121,4 @@ class TasksController < ApplicationController
.require(:task) .require(:task)
.permit(:name, :description, :duration, :user_list, :required_users, :workgroup_id, :due_date, :done) .permit(:name, :description, :duration, :user_list, :required_users, :workgroup_id, :due_date, :done)
end end
end end

View file

@ -1,5 +1,4 @@
class UsersController < ApplicationController class UsersController < ApplicationController
# Currently used to display users nick and ids for autocomplete # Currently used to display users nick and ids for autocomplete
def index def index
@users = User.undeleted.natural_search(params[:q]) @users = User.undeleted.natural_search(params[:q])
@ -7,5 +6,4 @@ class UsersController < ApplicationController
format.json { render :json => @users.map(&:token_attributes).to_json } format.json { render :json => @users.map(&:token_attributes).to_json }
end end
end end
end end

View file

@ -1,13 +1,11 @@
# encoding: utf-8
class OrderByArticles < OrderPdf class OrderByArticles < OrderPdf
def filename def filename
I18n.t('documents.order_by_articles.filename', :name => order.name, :date => order.ends.to_date) + '.pdf' I18n.t('documents.order_by_articles.filename', :name => order.name, :date => order.ends.to_date) + '.pdf'
end end
def title def title
I18n.t('documents.order_by_articles.title', :name => order.name, I18n.t('documents.order_by_articles.title', :name => order.name,
:date => order.ends.strftime(I18n.t('date.formats.default'))) :date => order.ends.strftime(I18n.t('date.formats.default')))
end end
def body def body

View file

@ -1,13 +1,11 @@
# encoding: utf-8
class OrderByGroups < OrderPdf class OrderByGroups < OrderPdf
def filename def filename
I18n.t('documents.order_by_groups.filename', :name => order.name, :date => order.ends.to_date) + '.pdf' I18n.t('documents.order_by_groups.filename', :name => order.name, :date => order.ends.to_date) + '.pdf'
end end
def title def title
I18n.t('documents.order_by_groups.title', :name => order.name, I18n.t('documents.order_by_groups.title', :name => order.name,
:date => order.ends.strftime(I18n.t('date.formats.default'))) :date => order.ends.strftime(I18n.t('date.formats.default')))
end end
def body def body
@ -25,14 +23,15 @@ class OrderByGroups < OrderPdf
each_group_order_article_for_ordergroup(oa_id) do |goa| each_group_order_article_for_ordergroup(oa_id) do |goa|
dimrows << rows.length if goa.result == 0 dimrows << rows.length if goa.result == 0
rows << [goa.order_article.article.name, rows << [goa.order_article.article.name,
goa.group_order.order.name, goa.group_order.order.name,
group_order_article_quantity_with_tolerance(goa), group_order_article_quantity_with_tolerance(goa),
group_order_article_result(goa), group_order_article_result(goa),
order_article_price_per_unit(goa.order_article), order_article_price_per_unit(goa.order_article),
number_to_currency(goa.total_price)] number_to_currency(goa.total_price)]
end end
next unless rows.length > 1 next unless rows.length > 1
rows << [nil, nil, nil, nil, nil, number_to_currency(oa_total)] rows << [nil, nil, nil, nil, nil, number_to_currency(oa_total)]
if has_transport if has_transport
rows << [GroupOrder.human_attribute_name(:transport), nil, nil, nil, nil, number_to_currency(oa_transport)] rows << [GroupOrder.human_attribute_name(:transport), nil, nil, nil, nil, number_to_currency(oa_transport)]
@ -64,5 +63,4 @@ class OrderByGroups < OrderPdf
end end
end end
end end
end end

View file

@ -1,6 +1,4 @@
# encoding: utf-8
class OrderFax < OrderPdf class OrderFax < OrderPdf
BATCH_SIZE = 250 BATCH_SIZE = 250
def filename def filename
@ -15,7 +13,7 @@ class OrderFax < OrderPdf
contact = FoodsoftConfig[:contact].symbolize_keys contact = FoodsoftConfig[:contact].symbolize_keys
# From paragraph # From paragraph
bounding_box [margin_box.right-200,margin_box.top], width: 200 do bounding_box [margin_box.right - 200, margin_box.top], width: 200 do
text FoodsoftConfig[:name], size: fontsize(9), align: :right text FoodsoftConfig[:name], size: fontsize(9), align: :right
move_down 5 move_down 5
text contact[:street], size: fontsize(9), align: :right text contact[:street], size: fontsize(9), align: :right
@ -36,7 +34,7 @@ class OrderFax < OrderPdf
end end
# Recipient # Recipient
bounding_box [margin_box.left,margin_box.top-60], width: 200 do bounding_box [margin_box.left, margin_box.top - 60], width: 200 do
text order.name text order.name
move_down 5 move_down 5
text order.supplier.try(:address).to_s text order.supplier.try(:address).to_s
@ -72,7 +70,7 @@ class OrderFax < OrderPdf
number_to_currency(subtotal)] number_to_currency(subtotal)]
end end
data << [I18n.t('documents.order_fax.total'), nil, nil, nil, nil, nil, number_to_currency(total)] data << [I18n.t('documents.order_fax.total'), nil, nil, nil, nil, nil, number_to_currency(total)]
table data, cell_style: {size: fontsize(8), overflow: :shrink_to_fit} do |table| table data, cell_style: { size: fontsize(8), overflow: :shrink_to_fit } do |table|
table.header = true table.header = true
table.cells.border_width = 1 table.cells.border_width = 1
table.cells.border_color = '666666' table.cells.border_color = '666666'
@ -80,28 +78,27 @@ class OrderFax < OrderPdf
table.row(0).border_bottom_width = 2 table.row(0).border_bottom_width = 2
table.columns(1).align = :right table.columns(1).align = :right
table.columns(3..6).align = :right table.columns(3..6).align = :right
table.row(data.length-1).columns(0..5).borders = [:top, :bottom] table.row(data.length - 1).columns(0..5).borders = [:top, :bottom]
table.row(data.length-1).columns(0).borders = [:top, :bottom, :left] table.row(data.length - 1).columns(0).borders = [:top, :bottom, :left]
table.row(data.length-1).border_top_width = 2 table.row(data.length - 1).border_top_width = 2
end end
#font_size: fontsize(8), # font_size: fontsize(8),
#vertical_padding: 3, # vertical_padding: 3,
#border_style: :grid, # border_style: :grid,
#headers: ["BestellNr.", "Menge","Name", "Gebinde", "Einheit","Preis/Einheit"], # headers: ["BestellNr.", "Menge","Name", "Gebinde", "Einheit","Preis/Einheit"],
#align: {0 => :left} # align: {0 => :left}
end end
private private
def order_articles def order_articles
order.order_articles.ordered. order.order_articles.ordered
joins(:article). .joins(:article)
order('articles.order_number').order('articles.name'). .order('articles.order_number').order('articles.name')
preload(:article, :article_price) .preload(:article, :article_price)
end end
def each_order_article def each_order_article
order_articles.find_each_with_order(batch_size: BATCH_SIZE) {|oa| yield oa } order_articles.find_each_with_order(batch_size: BATCH_SIZE) { |oa| yield oa }
end end
end end

View file

@ -1,5 +1,4 @@
class OrderMatrix < OrderPdf class OrderMatrix < OrderPdf
HEADER_ROTATE = -30 HEADER_ROTATE = -30
PLACEHOLDER_CHAR = 'X' PLACEHOLDER_CHAR = 'X'
@ -9,7 +8,7 @@ class OrderMatrix < OrderPdf
def title def title
I18n.t('documents.order_matrix.title', :name => @order.name, I18n.t('documents.order_matrix.title', :name => @order.name,
:date => @order.ends.strftime(I18n.t('date.formats.default'))) :date => @order.ends.strftime(I18n.t('date.formats.default')))
end end
def body def body
@ -31,7 +30,7 @@ class OrderMatrix < OrderPdf
order_articles_data.each { |row| row.delete_at 1 } unless @options[:show_supplier] order_articles_data.each { |row| row.delete_at 1 } unless @options[:show_supplier]
name = I18n.t('documents.order_matrix.heading', count: order_articles_data.size-1) name = I18n.t('documents.order_matrix.heading', count: order_articles_data.size - 1)
nice_table name, order_articles_data do |table| nice_table name, order_articles_data do |table|
if @options[:show_supplier] if @options[:show_supplier]
table.column(0).width = bounds.width / 3 table.column(0).width = bounds.width / 3
@ -82,7 +81,7 @@ class OrderMatrix < OrderPdf
rows << row rows << row
end end
table rows, header: true, cell_style: {overflow: :shrink_to_fit} do |table| table rows, header: true, cell_style: { overflow: :shrink_to_fit } do |table|
table.cells.padding = [0, 0, 2, 0] table.cells.padding = [0, 0, 2, 0]
table.cells.borders = [:left] table.cells.borders = [:left]
table.cells.border_width = 0.5 table.cells.border_width = 0.5
@ -95,8 +94,8 @@ class OrderMatrix < OrderPdf
table.column(1).align = :right table.column(1).align = :right
table.column(1).padding = [0, 3, 2, 0] table.column(1).padding = [0, 3, 2, 0]
table.column(2..-1).align = :center table.column(2..-1).align = :center
table.cells[0,0].borders = [] table.cells[0, 0].borders = []
table.cells[0,1].borders = [] table.cells[0, 1].borders = []
table.column(0).overflow = :truncate table.column(0).overflow = :truncate
table.column(0).width = col_width_0 table.column(0).width = col_width_0
@ -104,7 +103,7 @@ class OrderMatrix < OrderPdf
table.column(2..-1).width = col_width_2 table.column(2..-1).width = col_width_2
(0..batch_size).step(5).each do |idx| (0..batch_size).step(5).each do |idx|
table.column(2+idx).border_width = 2 table.column(2 + idx).border_width = 2
end end
table.row_colors = ['dddddd', 'ffffff'] table.row_colors = ['dddddd', 'ffffff']
@ -113,5 +112,4 @@ class OrderMatrix < OrderPdf
first_page = false first_page = false
end end
end end
end end

View file

@ -11,13 +11,14 @@ module Admin::ConfigsHelper
# @todo find way to pass current value to time_zone input without using default # @todo find way to pass current value to time_zone input without using default
def config_input(form, key, options = {}, &block) def config_input(form, key, options = {}, &block)
return unless @cfg.allowed_key? key return unless @cfg.allowed_key? key
options[:label] ||= config_input_label(form, key) options[:label] ||= config_input_label(form, key)
options[:required] ||= false options[:required] ||= false
options[:input_html] ||= {} options[:input_html] ||= {}
config_input_field_options form, key, options[:input_html] config_input_field_options form, key, options[:input_html]
config_input_tooltip_options form, key, options[:input_html] config_input_tooltip_options form, key, options[:input_html]
if options[:as] == :boolean if options[:as] == :boolean
options[:input_html][:checked] = 'checked' if v=options[:input_html].delete(:value) && v!='false' options[:input_html][:checked] = 'checked' if v = options[:input_html].delete(:value) && v != 'false'
options[:checked_value] = 'true' if options[:checked_value].nil? options[:checked_value] = 'true' if options[:checked_value].nil?
options[:unchecked_value] = 'false' if options[:unchecked_value].nil? options[:unchecked_value] = 'false' if options[:unchecked_value].nil?
elsif options[:collection] || options[:as] == :select elsif options[:collection] || options[:as] == :select
@ -47,13 +48,14 @@ module Admin::ConfigsHelper
# @todo find out how to pass +checked_value+ and +unchecked_value+ to +input_field+ # @todo find out how to pass +checked_value+ and +unchecked_value+ to +input_field+
def config_input_field(form, key, options = {}) def config_input_field(form, key, options = {})
return unless @cfg.allowed_key? :key return unless @cfg.allowed_key? :key
options[:required] ||= false options[:required] ||= false
config_input_field_options form, key, options config_input_field_options form, key, options
config_input_tooltip_options form, key, options config_input_tooltip_options form, key, options
if options[:as] == :boolean if options[:as] == :boolean
checked_value = options.delete(:checked_value) || 'true' checked_value = options.delete(:checked_value) || 'true'
unchecked_value = options.delete(:unchecked_value) || 'false' unchecked_value = options.delete(:unchecked_value) || 'false'
options[:checked] = 'checked' if v=options.delete(:value) && v!='false' options[:checked] = 'checked' if v = options.delete(:value) && v != 'false'
# different key for hidden field so that allow clocking on label focuses the control # different key for hidden field so that allow clocking on label focuses the control
form.hidden_field(key, id: "#{key}_", value: unchecked_value, as: :hidden) + form.check_box(key, options, checked_value, false) form.hidden_field(key, id: "#{key}_", value: unchecked_value, as: :hidden) + form.check_box(key, options, checked_value, false)
elsif options[:as] == :select_recurring elsif options[:as] == :select_recurring
@ -73,13 +75,13 @@ module Admin::ConfigsHelper
# @option options [String] :label Label to show # @option options [String] :label Label to show
def config_use_heading(form, key, options = {}) def config_use_heading(form, key, options = {})
head = content_tag :label do head = content_tag :label do
lbl = options[:label] || config_input_label(form, key) lbl = options[:label] || config_input_label(form, key)
field = config_input_field(form, key, as: :boolean, boolean_style: :inline, field = config_input_field(form, key, as: :boolean, boolean_style: :inline,
data: {toggle: 'collapse', target: "##{key}-fields"}) data: { toggle: 'collapse', target: "##{key}-fields" })
content_tag :h4 do content_tag :h4 do
# put in span to keep space for tooltip at right # put in span to keep space for tooltip at right
content_tag :span, (lbl + field).html_safe, config_input_tooltip_options(form, key, {}) content_tag :span, (lbl + field).html_safe, config_input_tooltip_options(form, key, {})
end end
end end
fields = content_tag(:fieldset, id: "#{key}-fields", class: "collapse#{' in' if @cfg[key]}") do fields = content_tag(:fieldset, id: "#{key}-fields", class: "collapse#{' in' if @cfg[key]}") do
yield yield
@ -99,12 +101,12 @@ module Admin::ConfigsHelper
'(protected)' '(protected)'
elsif value.is_a? Hash elsif value.is_a? Hash
content_tag :ul do content_tag :ul do
value.map do |k,v| value.map do |k, v|
content_tag :li, content_tag(:tt, "#{k}: ") + show_config_value(k, v).to_s content_tag :li, content_tag(:tt, "#{k}: ") + show_config_value(k, v).to_s
end.join.html_safe end.join.html_safe
end end
elsif value.is_a? Enumerable elsif value.is_a? Enumerable
content_tag :ul, value.map {|v| content_tag :li, h(v)}.join.html_safe content_tag :ul, value.map { |v| content_tag :li, h(v) }.join.html_safe
elsif key =~ /url|website|www|homepage/ elsif key =~ /url|website|www|homepage/
link_to(value, value.to_s).html_safe link_to(value, value.to_s).html_safe
else else
@ -115,7 +117,7 @@ module Admin::ConfigsHelper
# @return [String] Tooltip element (span) # @return [String] Tooltip element (span)
# @param form [ActionView::Helpers::FormBuilder] Form object. # @param form [ActionView::Helpers::FormBuilder] Form object.
# @param key [Symbol, String] Configuration key of a boolean (e.g. +use_messages+). # @param key [Symbol, String] Configuration key of a boolean (e.g. +use_messages+).
def config_tooltip(form, key, options={}, &block) def config_tooltip(form, key, options = {}, &block)
content_tag :span, config_input_tooltip_options(form, key, options), &block content_tag :span, config_input_tooltip_options(form, key, options), &block
end end
@ -139,7 +141,7 @@ module Admin::ConfigsHelper
# set current value # set current value
unless options.has_key?(:value) unless options.has_key?(:value)
value = @cfg value = @cfg
cfg_path.each {|n| value = value[n] if value.respond_to? :[] } cfg_path.each { |n| value = value[n] if value.respond_to? :[] }
options[:value] = value options[:value] = value
end end
options options

View file

@ -1,4 +1,3 @@
# encoding: utf-8
# #
# Methods added to this helper will be available to all templates in the application. # Methods added to this helper will be available to all templates in the application.
module ApplicationHelper module ApplicationHelper
@ -27,14 +26,14 @@ module ApplicationHelper
# Splits an IBAN into groups of 4 digits displayed with margins in between # Splits an IBAN into groups of 4 digits displayed with margins in between
def format_iban(iban) def format_iban(iban)
iban.scan(/..?.?.?/).map{ |item| content_tag(:span, item, style: "margin-right: 0.5em;") }.join.html_safe iban.scan(/..?.?.?/).map { |item| content_tag(:span, item, style: "margin-right: 0.5em;") }.join.html_safe
end end
# Creates ajax-controlled-links for pagination # Creates ajax-controlled-links for pagination
def pagination_links_remote(collection, options = {}) def pagination_links_remote(collection, options = {})
per_page = options[:per_page] || @per_page per_page = options[:per_page] || @per_page
params = options[:params] || {} params = options[:params] || {}
params = params.merge({:per_page => per_page}) params = params.merge({ :per_page => per_page })
paginate collection, :params => params, :remote => true paginate collection, :params => params, :remote => true
end end
@ -45,7 +44,7 @@ module ApplicationHelper
params = params || {} params = params || {}
links = per_page_options.map do |per_page| links = per_page_options.map do |per_page|
params.merge!({:per_page => per_page}) params.merge!({ :per_page => per_page })
link_class = 'btn' link_class = 'btn'
link_class << ' disabled' if per_page == current link_class << ' disabled' if per_page == current
link_to(per_page, params, :remote => true, class: link_class) link_to(per_page, params, :remote => true, class: link_class)
@ -58,33 +57,31 @@ module ApplicationHelper
links.join.html_safe links.join.html_safe
end end
end end
end end
def sort_link_helper(text, key, options = {}) def sort_link_helper(text, key, options = {})
# Hmtl options # Hmtl options
remote = options[:remote].nil? ? true : options[:remote] remote = options[:remote].nil? ? true : options[:remote]
class_name = case params[:sort] class_name = case params[:sort]
when key then when key then
'sortup' 'sortup'
when key + '_reverse' then when key + '_reverse' then
'sortdown' 'sortdown'
else else
nil nil
end end
html_options = { html_options = {
:title => I18n.t('helpers.application.sort_by', text: text), :title => I18n.t('helpers.application.sort_by', text: text),
:remote => remote, :remote => remote,
:class => class_name :class => class_name
} }
# Url options # Url options
key += "_reverse" if params[:sort] == key key += "_reverse" if params[:sort] == key
per_page = options[:per_page] || @per_page per_page = options[:per_page] || @per_page
url_options = params.merge(per_page: per_page, sort: key) url_options = params.merge(per_page: per_page, sort: key)
url_options.merge!({page: params[:page]}) if params[:page] url_options.merge!({ page: params[:page] }) if params[:page]
url_options.merge!({query: params[:query]}) if params[:query] url_options.merge!({ query: params[:query] }) if params[:query]
link_to(text, url_for(url_options), html_options) link_to(text, url_for(url_options), html_options)
end end
@ -98,13 +95,13 @@ module ApplicationHelper
# be overridden by the option 'desc'. # be overridden by the option 'desc'.
# Other options are passed through to I18n. # Other options are passed through to I18n.
def heading_helper(model, attribute, options = {}) def heading_helper(model, attribute, options = {})
i18nopts = {count: 2}.merge(options.select {|a| !['short', 'desc'].include?(a) }) i18nopts = { count: 2 }.merge(options.select { |a| !['short', 'desc'].include?(a) })
s = model.human_attribute_name(attribute, i18nopts) s = model.human_attribute_name(attribute, i18nopts)
if options[:short] if options[:short]
desc = options[:desc] desc = options[:desc]
desc ||= model.human_attribute_name("#{attribute}_desc".to_sym, options.merge({fallback: true, default: '', count: 2})) desc ||= model.human_attribute_name("#{attribute}_desc".to_sym, options.merge({ fallback: true, default: '', count: 2 }))
desc.blank? && desc = s desc.blank? && desc = s
sshort = model.human_attribute_name("#{attribute}_short".to_sym, options.merge({fallback: true, default: '', count: 2})) sshort = model.human_attribute_name("#{attribute}_short".to_sym, options.merge({ fallback: true, default: '', count: 2 }))
s = raw "<abbr title='#{desc}'>#{sshort}</abbr>" unless sshort.blank? s = raw "<abbr title='#{desc}'>#{sshort}</abbr>" unless sshort.blank?
end end
s s
@ -134,24 +131,24 @@ module ApplicationHelper
end end
def tab_is_active?(tab) def tab_is_active?(tab)
tab[:active].detect {|c| controller.controller_path.match(c) } tab[:active].detect { |c| controller.controller_path.match(c) }
end end
def icon(name, options={}) def icon(name, options = {})
icons = { icons = {
:delete => { :file => 'b_drop.png', :alt => I18n.t('ui.delete')}, :delete => { :file => 'b_drop.png', :alt => I18n.t('ui.delete') },
:edit => { :file => 'b_edit.png', :alt => I18n.t('ui.edit')}, :edit => { :file => 'b_edit.png', :alt => I18n.t('ui.edit') },
:members => { :file => 'b_users.png', :alt => I18n.t('helpers.application.edit_user')} :members => { :file => 'b_users.png', :alt => I18n.t('helpers.application.edit_user') }
} }
options[:alt] ||= icons[name][:alt] options[:alt] ||= icons[name][:alt]
options[:title] ||= icons[name][:title] options[:title] ||= icons[name][:title]
options.merge!({:size => '16x16',:border => "0"}) options.merge!({ :size => '16x16', :border => "0" })
image_tag icons[name][:file], options image_tag icons[name][:file], options
end end
# Remote links with default 'loader'.gif during request # Remote links with default 'loader'.gif during request
def remote_link_to(text, options={}) def remote_link_to(text, options = {})
remote_options = { remote_options = {
:before => "Element.show('loader')", :before => "Element.show('loader')",
:success => "Element.hide('loader')", :success => "Element.hide('loader')",
@ -160,20 +157,20 @@ module ApplicationHelper
link_to(text, options[:url], remote_options.merge(options)) link_to(text, options[:url], remote_options.merge(options))
end end
def format_roles(record, icon=false) def format_roles(record, icon = false)
roles = %w(suppliers article_meta orders pickups finance invoices admin) roles = %w(suppliers article_meta orders pickups finance invoices admin)
roles.select! {|role| record.send "role_#{role}?"} roles.select! { |role| record.send "role_#{role}?" }
names = Hash[roles.map{|r| [r, I18n.t("helpers.application.role_#{r}")]}] names = Hash[roles.map { |r| [r, I18n.t("helpers.application.role_#{r}")] }]
if icon if icon
roles.map{|r| image_tag("role-#{r}.png", size: '22x22', border: 0, alt: names[r], title: names[r])}.join('&nbsp;').html_safe roles.map { |r| image_tag("role-#{r}.png", size: '22x22', border: 0, alt: names[r], title: names[r]) }.join('&nbsp;').html_safe
else else
roles.map{|r| names[r]}.join(', ') roles.map { |r| names[r] }.join(', ')
end end
end end
def link_to_gmaps(address) def link_to_gmaps(address)
link_to h(address), "http://maps.google.com/?q=#{h(address)}", :title => I18n.t('helpers.application.show_google_maps'), link_to h(address), "http://maps.google.com/?q=#{h(address)}", :title => I18n.t('helpers.application.show_google_maps'),
:target => "_blank" :target => "_blank"
end end
# Returns flash messages html. # Returns flash messages html.
@ -200,12 +197,13 @@ module ApplicationHelper
# http://railsapps.github.io/twitter-bootstrap-rails.html # http://railsapps.github.io/twitter-bootstrap-rails.html
def base_errors resource def base_errors resource
return '' if resource.errors.empty? || resource.errors[:base].empty? return '' if resource.errors.empty? || resource.errors[:base].empty?
messages = resource.errors[:base].map { |msg| content_tag(:li, msg) }.join messages = resource.errors[:base].map { |msg| content_tag(:li, msg) }.join
render :partial => 'shared/base_errors', :locals => {:error_messages => messages} render :partial => 'shared/base_errors', :locals => { :error_messages => messages }
end end
# show a user, depending on settings # show a user, depending on settings
def show_user(user=@current_user, options = {}) def show_user(user = @current_user, options = {})
if user.nil? if user.nil?
"?" "?"
elsif FoodsoftConfig[:use_nick] elsif FoodsoftConfig[:use_nick]
@ -223,13 +221,14 @@ module ApplicationHelper
end end
# render user presentation linking to default action (plugins can override this) # render user presentation linking to default action (plugins can override this)
def show_user_link(user=@current_user) def show_user_link(user = @current_user)
show_user user show_user user
end end
# allow truncate to add title when tooltip option is given # allow truncate to add title when tooltip option is given
def truncate(text, options={}, &block) def truncate(text, options = {}, &block)
return text if !text || text.length <= (options[:length] || 30) return text if !text || text.length <= (options[:length] || 30)
text_truncated = super(text, options, &block) text_truncated = super(text, options, &block)
if options[:tooltip] if options[:tooltip]
content_tag :span, text_truncated, title: text content_tag :span, text_truncated, title: text
@ -240,29 +239,28 @@ module ApplicationHelper
# Expand variables in text # Expand variables in text
# @see Foodsoft::ExpansionVariables#expand # @see Foodsoft::ExpansionVariables#expand
def expand(text, options={}) def expand(text, options = {})
Foodsoft::ExpansionVariables.expand(text, options) Foodsoft::ExpansionVariables.expand(text, options)
end end
# @param dismiss [String, Symbol] Bootstrap dismiss value (modal, alert) # @param dismiss [String, Symbol] Bootstrap dismiss value (modal, alert)
# @return [String] HTML for close button dismissing # @return [String] HTML for close button dismissing
def close_button(dismiss) def close_button(dismiss)
content_tag :button, type: 'button', class: 'close', data: {dismiss: dismiss} do content_tag :button, type: 'button', class: 'close', data: { dismiss: dismiss } do
I18n.t('ui.marks.close').html_safe I18n.t('ui.marks.close').html_safe
end end
end end
# @return [String] path to foodcoop CSS style (with MD5 parameter for caching) # @return [String] path to foodcoop CSS style (with MD5 parameter for caching)
def foodcoop_css_path(options={}) def foodcoop_css_path(options = {})
super(options.merge({md5: Digest::MD5.hexdigest(FoodsoftConfig[:custom_css].to_s)})) super(options.merge({ md5: Digest::MD5.hexdigest(FoodsoftConfig[:custom_css].to_s) }))
end end
# @return [String] stylesheet tag for foodcoop CSS style (+custom_css+ foodcoop config) # @return [String] stylesheet tag for foodcoop CSS style (+custom_css+ foodcoop config)
# @see #foodcoop_css_path # @see #foodcoop_css_path
def foodcoop_css_tag(options={}) def foodcoop_css_tag(options = {})
unless FoodsoftConfig[:custom_css].blank? unless FoodsoftConfig[:custom_css].blank?
stylesheet_link_tag foodcoop_css_path, media: 'all' stylesheet_link_tag foodcoop_css_path, media: 'all'
end end
end end
end end

View file

@ -1,8 +1,8 @@
module ArticlesHelper module ArticlesHelper
# useful for highlighting attributes, when synchronizing articles # useful for highlighting attributes, when synchronizing articles
def highlight_new(unequal_attributes, attribute) def highlight_new(unequal_attributes, attribute)
return unless unequal_attributes return unless unequal_attributes
unequal_attributes.has_key?(attribute) ? "background-color: yellow" : "" unequal_attributes.has_key?(attribute) ? "background-color: yellow" : ""
end end

View file

@ -1,33 +1,32 @@
module DeliveriesHelper module DeliveriesHelper
def link_to_invoice(delivery) def link_to_invoice(delivery)
if delivery.invoice if delivery.invoice
link_to number_to_currency(delivery.invoice.amount), [:finance, delivery.invoice], link_to number_to_currency(delivery.invoice.amount), [:finance, delivery.invoice],
title: I18n.t('helpers.deliveries.show_invoice') title: I18n.t('helpers.deliveries.show_invoice')
else else
link_to I18n.t('helpers.deliveries.new_invoice'), new_finance_invoice_path(supplier_id: delivery.supplier.id, delivery_id: delivery.id), link_to I18n.t('helpers.deliveries.new_invoice'), new_finance_invoice_path(supplier_id: delivery.supplier.id, delivery_id: delivery.id),
class: 'btn btn-mini' class: 'btn btn-mini'
end end
end end
def articles_for_select2(articles, except = [], &block) def articles_for_select2(articles, except = [], &block)
articles = articles.reorder('articles.name ASC') articles = articles.reorder('articles.name ASC')
articles = articles.reject {|a| not except.index(a.id).nil? } if except articles = articles.reject { |a| not except.index(a.id).nil? } if except
block_given? or block = Proc.new {|a| "#{a.name} (#{number_to_currency a.price}/#{a.unit})" } block_given? or block = Proc.new { |a| "#{a.name} (#{number_to_currency a.price}/#{a.unit})" }
articles.map do |a| articles.map do |a|
{:id => a.id, :text => block.call(a)} { :id => a.id, :text => block.call(a) }
end.unshift({:id => '', :text => ''}) end.unshift({ :id => '', :text => '' })
end end
def articles_for_table(articles) def articles_for_table(articles)
articles.undeleted.reorder('articles.name ASC') articles.undeleted.reorder('articles.name ASC')
end end
def stock_change_remove_link(stock_change_form) def stock_change_remove_link(stock_change_form)
return link_to t('deliveries.stock_change_fields.remove_article'), "#", :class => 'remove_new_stock_change btn btn-small' if stock_change_form.object.new_record? return link_to t('deliveries.stock_change_fields.remove_article'), "#", :class => 'remove_new_stock_change btn btn-small' if stock_change_form.object.new_record?
output = stock_change_form.hidden_field :_destroy output = stock_change_form.hidden_field :_destroy
output += link_to t('deliveries.stock_change_fields.remove_article'), "#", :class => 'destroy_stock_change btn btn-small' output += link_to t('deliveries.stock_change_fields.remove_article'), "#", :class => 'destroy_stock_change btn btn-small'
return output.html_safe return output.html_safe
end end
end end

View file

@ -2,12 +2,12 @@ module Finance::BalancingHelper
def balancing_view_partial def balancing_view_partial
view = params[:view] || 'edit_results' view = params[:view] || 'edit_results'
case view case view
when 'edit_results' then when 'edit_results' then
'edit_results_by_articles' 'edit_results_by_articles'
when 'groups_overview' then when 'groups_overview' then
'shared/articles_by/groups' 'shared/articles_by/groups'
when 'articles_overview' then when 'articles_overview' then
'shared/articles_by/articles' 'shared/articles_by/articles'
end end
end end
end end

View file

@ -2,6 +2,7 @@ module Finance::InvoicesHelper
def format_delivery_item delivery def format_delivery_item delivery
format_date(delivery.date) format_date(delivery.date)
end end
def format_order_item order def format_order_item order
"#{format_date(order.ends)} (#{number_to_currency(order.sum)})" "#{format_date(order.ends)} (#{number_to_currency(order.sum)})"
end end

View file

@ -1,15 +1,13 @@
module GroupOrderArticlesHelper module GroupOrderArticlesHelper
# return an edit field for a GroupOrderArticle result # return an edit field for a GroupOrderArticle result
def group_order_article_edit_result(goa) def group_order_article_edit_result(goa)
result = number_with_precision goa.result, strip_insignificant_zeros: true result = number_with_precision goa.result, strip_insignificant_zeros: true
unless goa.group_order.order.finished? && current_user.role_finance? unless goa.group_order.order.finished? && current_user.role_finance?
result result
else else
simple_form_for goa, remote: true, html: {'data-submit-onchange' => 'changed', class: 'delta-input'} do |f| simple_form_for goa, remote: true, html: { 'data-submit-onchange' => 'changed', class: 'delta-input' } do |f|
f.input_field :result, as: :delta, class: 'input-nano', data: {min: 0}, id: "r_#{goa.id}", value: result f.input_field :result, as: :delta, class: 'input-nano', data: { min: 0 }, id: "r_#{goa.id}", value: result
end end
end end
end end
end end

View file

@ -12,12 +12,12 @@ module GroupOrdersHelper
def link_to_ordering(order, options = {}, &block) def link_to_ordering(order, options = {}, &block)
group_order = order.group_order(current_user.ordergroup) group_order = order.group_order(current_user.ordergroup)
path = if options[:show] && group_order path = if options[:show] && group_order
group_order_path(group_order) group_order_path(group_order)
elsif group_order elsif group_order
edit_group_order_path(group_order, :order_id => order.id) edit_group_order_path(group_order, :order_id => order.id)
else else
new_group_order_path(:order_id => order.id) new_group_order_path(:order_id => order.id)
end end
options.delete(:show) options.delete(:show)
name = block_given? ? capture(&block) : order.name name = block_given? ? capture(&block) : order.name
path ? link_to(name, path, options) : name path ? link_to(name, path, options) : name
@ -36,18 +36,18 @@ module GroupOrdersHelper
def get_order_results(order_article, group_order_id) def get_order_results(order_article, group_order_id)
goa = order_article.group_order_articles.detect { |goa| goa.group_order_id == group_order_id } goa = order_article.group_order_articles.detect { |goa| goa.group_order_id == group_order_id }
quantity, tolerance, result, sub_total = if goa.present? quantity, tolerance, result, sub_total = if goa.present?
[goa.quantity, goa.tolerance, goa.result, goa.total_price(order_article)] [goa.quantity, goa.tolerance, goa.result, goa.total_price(order_article)]
else else
[0, 0, 0, 0] [0, 0, 0, 0]
end end
{group_order_article: goa, quantity: quantity, tolerance: tolerance, result: result, sub_total: sub_total} { group_order_article: goa, quantity: quantity, tolerance: tolerance, result: result, sub_total: sub_total }
end end
def get_missing_units_css_class(quantity_missing) def get_missing_units_css_class(quantity_missing)
if ( quantity_missing == 1 ) if (quantity_missing == 1)
return 'missing-few'; return 'missing-few';
elsif ( quantity_missing == 0 ) elsif (quantity_missing == 0)
return '' return ''
else else
return 'missing-many' return 'missing-many'

View file

@ -1,8 +1,6 @@
module OrderArticlesHelper module OrderArticlesHelper
def article_label_with_unit(article) def article_label_with_unit(article)
pkg_info = pkg_helper(article, plain: true) pkg_info = pkg_helper(article, plain: true)
"#{article.name} (#{[article.unit, pkg_info].reject(&:blank?).join(' ')})" "#{article.name} (#{[article.unit, pkg_info].reject(&:blank?).join(' ')})"
end end
end end

View file

@ -1,8 +1,6 @@
# encoding: utf-8
module OrdersHelper module OrdersHelper
def update_articles_link(order, text, view, options = {})
def update_articles_link(order, text, view, options={}) options = { remote: true, id: "view_#{view}_btn", class: '' }.merge(options)
options = {remote: true, id: "view_#{view}_btn", class: ''}.merge(options)
options[:class] += ' active' if view.to_s == @view.to_s options[:class] += ' active' if view.to_s == @view.to_s
link_to text, order_path(order, view: view), options link_to text, order_path(order, view: view), options
end end
@ -13,20 +11,20 @@ module OrdersHelper
# @param options [Hash] Options passed to +link_to+ # @param options [Hash] Options passed to +link_to+
# @return [String] Link to order document # @return [String] Link to order document
# @see OrdersController#show # @see OrdersController#show
def order_pdf(order, document, text, options={}) def order_pdf(order, document, text, options = {})
options = options.merge(title: I18n.t('helpers.orders.order_pdf')) options = options.merge(title: I18n.t('helpers.orders.order_pdf'))
link_to text, order_path(order, document: document, format: :pdf), options link_to text, order_path(order, document: document, format: :pdf), options
end end
def options_for_suppliers_to_select def options_for_suppliers_to_select
options = [[I18n.t('helpers.orders.option_choose')]] options = [[I18n.t('helpers.orders.option_choose')]]
options += Supplier.map {|s| [ s.name, url_for(action: "new", supplier_id: s.id)] } options += Supplier.map { |s| [s.name, url_for(action: "new", supplier_id: s.id)] }
options += [[I18n.t('helpers.orders.option_stock'), url_for(action: 'new', supplier_id: nil)]] options += [[I18n.t('helpers.orders.option_stock'), url_for(action: 'new', supplier_id: nil)]]
options_for_select(options) options_for_select(options)
end end
# "1×2 ordered, 2×2 billed, 2×2 received" # "1×2 ordered, 2×2 billed, 2×2 received"
def units_history_line(order_article, options={}) def units_history_line(order_article, options = {})
if order_article.order.open? if order_article.order.open?
nil nil
else else
@ -49,8 +47,9 @@ module OrdersHelper
# @option options [String] :soft_uq +true+ to hide unit quantity specifier on small screens. # @option options [String] :soft_uq +true+ to hide unit quantity specifier on small screens.
# Sensible in tables with multiple columns. # Sensible in tables with multiple columns.
# @return [String] Text showing unit and unit quantity when applicable. # @return [String] Text showing unit and unit quantity when applicable.
def pkg_helper(article, options={}) def pkg_helper(article, options = {})
return '' if !article || article.unit_quantity == 1 return '' if !article || article.unit_quantity == 1
uq_text = "× #{article.unit_quantity}" uq_text = "× #{article.unit_quantity}"
uq_text = content_tag(:span, uq_text, class: 'hidden-phone') if options[:soft_uq] uq_text = content_tag(:span, uq_text, class: 'hidden-phone') if options[:soft_uq]
if options[:plain] if options[:plain]
@ -61,11 +60,12 @@ module OrdersHelper
pkg_helper_icon(uq_text, tag: :span) pkg_helper_icon(uq_text, tag: :span)
end end
end end
# @param c [Symbol, String] Tag to use # @param c [Symbol, String] Tag to use
# @option options [String] :class CSS class(es) (in addition to +package+) # @option options [String] :class CSS class(es) (in addition to +package+)
# @return [String] Icon used for displaying the unit quantity # @return [String] Icon used for displaying the unit quantity
def pkg_helper_icon(c=nil, options={}) def pkg_helper_icon(c = nil, options = {})
options = {tag: 'i', class: ''}.merge(options) options = { tag: 'i', class: '' }.merge(options)
if c.nil? if c.nil?
c = "&nbsp;".html_safe c = "&nbsp;".html_safe
options[:class] += " icon-only" options[:class] += " icon-only"
@ -73,8 +73,9 @@ module OrdersHelper
content_tag(options[:tag], c, class: "package #{options[:class]}").html_safe content_tag(options[:tag], c, class: "package #{options[:class]}").html_safe
end end
def article_price_change_hint(order_article, gross=false) def article_price_change_hint(order_article, gross = false)
return nil if order_article.article.price == order_article.price.price return nil if order_article.article.price == order_article.price.price
title = "#{t('helpers.orders.old_price')}: #{number_to_currency order_article.article.price}" title = "#{t('helpers.orders.old_price')}: #{number_to_currency order_article.article.price}"
title += " / #{number_to_currency order_article.article.gross_price}" if gross title += " / #{number_to_currency order_article.article.gross_price}" if gross
content_tag(:i, nil, class: 'icon-asterisk', title: j(title)).html_safe content_tag(:i, nil, class: 'icon-asterisk', title: j(title)).html_safe
@ -83,14 +84,14 @@ module OrdersHelper
def receive_input_field(form) def receive_input_field(form)
order_article = form.object order_article = form.object
units_expected = (order_article.units_billed || order_article.units_to_order) * units_expected = (order_article.units_billed || order_article.units_to_order) *
1.0 * order_article.article.unit_quantity / order_article.article_price.unit_quantity 1.0 * order_article.article.unit_quantity / order_article.article_price.unit_quantity
input_classes = 'input input-nano units_received' input_classes = 'input input-nano units_received'
input_classes += ' package' unless order_article.article_price.unit_quantity == 1 input_classes += ' package' unless order_article.article_price.unit_quantity == 1
input_html = form.text_field :units_received, class: input_classes, input_html = form.text_field :units_received, class: input_classes,
data: {'units-expected' => units_expected}, data: { 'units-expected' => units_expected },
disabled: order_article.result_manually_changed?, disabled: order_article.result_manually_changed?,
autocomplete: 'off' autocomplete: 'off'
if order_article.result_manually_changed? if order_article.result_manually_changed?
input_html = content_tag(:span, class: 'input-prepend intable', title: t('orders.edit_amount.field_locked_title', default: '')) { input_html = content_tag(:span, class: 'input-prepend intable', title: t('orders.edit_amount.field_locked_title', default: '')) {
@ -111,7 +112,7 @@ module OrdersHelper
if group_orders.count == 0 if group_orders.count == 0
return txt return txt
else else
desc = group_orders.includes(:ordergroup).map {|g| g.ordergroup_name}.join(', ') desc = group_orders.includes(:ordergroup).map { |g| g.ordergroup_name }.join(', ')
content_tag(:abbr, txt, title: desc).html_safe content_tag(:abbr, txt, title: desc).html_safe
end end
end end
@ -147,7 +148,7 @@ module OrdersHelper
# @param order [Order] # @param order [Order]
# @option options [String] :class Classes added to the button's class attribute. # @option options [String] :class Classes added to the button's class attribute.
# @return [String] Order receive button. # @return [String] Order receive button.
def receive_button(order, options={}) def receive_button(order, options = {})
if order.stockit? if order.stockit?
content_tag :div, t('orders.index.action_receive'), class: "btn disabled #{options[:class]}" content_tag :div, t('orders.index.action_receive'), class: "btn disabled #{options[:class]}"
else else

View file

@ -1,5 +1,4 @@
module PathHelper module PathHelper
def finance_group_transactions_path(ordergroup) def finance_group_transactions_path(ordergroup)
if ordergroup if ordergroup
finance_ordergroup_transactions_path(ordergroup) finance_ordergroup_transactions_path(ordergroup)
@ -7,5 +6,4 @@ module PathHelper
finance_foodcoop_financial_transactions_path finance_foodcoop_financial_transactions_path
end end
end end
end end

View file

@ -1,13 +1,11 @@
module SharedHelper module SharedHelper
# provide input_html for password autocompletion # provide input_html for password autocompletion
def autocomplete_flag_to_password_html(password_autocomplete) def autocomplete_flag_to_password_html(password_autocomplete)
case password_autocomplete case password_autocomplete
when true then {autocomplete: 'on'} when true then { autocomplete: 'on' }
when false then {autocomplete: 'off'} when false then { autocomplete: 'off' }
when 'store-only' then {autocomplete: 'off', data: {store: 'on'}} when 'store-only' then { autocomplete: 'off', data: { store: 'on' } }
else {} else {}
end end
end end
end end

View file

@ -18,9 +18,7 @@ module StockitHelper
def stock_article_price_hint(stock_article) def stock_article_price_hint(stock_article)
t('simple_form.hints.stock_article.edit_stock_article.price', t('simple_form.hints.stock_article.edit_stock_article.price',
:stock_article_copy_link => link_to(t('stockit.form.copy_stock_article'), :stock_article_copy_link => link_to(t('stockit.form.copy_stock_article'),
stock_article_copy_path(stock_article), stock_article_copy_path(stock_article),
:remote => true :remote => true))
)
)
end end
end end

View file

@ -1,5 +1,4 @@
module SuppliersHelper module SuppliersHelper
def associated_supplier_names(shared_supplier) def associated_supplier_names(shared_supplier)
"(#{shared_supplier.suppliers.map(&:name).join(', ')})" "(#{shared_supplier.suppliers.map(&:name).join(', ')})"
end end

View file

@ -1,5 +1,4 @@
module TasksHelper module TasksHelper
def task_assignments(task) def task_assignments(task)
task.assignments.map do |ass| task.assignments.map do |ass|
content_tag :span, show_user(ass.user), :class => (ass.accepted? ? 'accepted' : 'unaccepted') content_tag :span, show_user(ass.user), :class => (ass.accepted? ? 'accepted' : 'unaccepted')
@ -10,7 +9,7 @@ module TasksHelper
def highlighted_required_users(task) def highlighted_required_users(task)
unless task.enough_users_assigned? unless task.enough_users_assigned?
content_tag :span, task.still_required_users, class: 'badge badge-important', content_tag :span, task.still_required_users, class: 'badge badge-important',
title: I18n.t('helpers.tasks.required_users', :count => task.still_required_users) title: I18n.t('helpers.tasks.required_users', :count => task.still_required_users)
end end
end end

View file

@ -12,12 +12,12 @@ class DatePickerTimeInput < SimpleForm::Inputs::StringInput
# In the future, use html5 date&time inputs. This needs modernizr or equiv. to avoid # In the future, use html5 date&time inputs. This needs modernizr or equiv. to avoid
# double widgets, and perhaps conditional css to adjust input width (chrome). # double widgets, and perhaps conditional css to adjust input width (chrome).
value = @builder.object.send attribute_name value = @builder.object.send attribute_name
date_options = {as: :string, class: 'input-small datepicker'} date_options = { as: :string, class: 'input-small datepicker' }
time_options = {as: :string, class: 'input-mini'} time_options = { as: :string, class: 'input-mini' }
@builder.input_field("#{attribute_name}_date_value", options.merge(date_options)) + ' ' + @builder.input_field("#{attribute_name}_date_value", options.merge(date_options)) + ' ' +
@builder.input_field("#{attribute_name}_time_value", options.merge(time_options)) @builder.input_field("#{attribute_name}_time_value", options.merge(time_options))
# time_select requires a date_select # time_select requires a date_select
#@builder.time_select("#{attribute_name}_time", {ignore_date: true}, input_html_options.merge(time_options)) # @builder.time_select("#{attribute_name}_time", {ignore_date: true}, input_html_options.merge(time_options))
end end
def label_target def label_target

View file

@ -1,5 +1,3 @@
# encoding: utf-8
class DeltaInput < SimpleForm::Inputs::StringInput class DeltaInput < SimpleForm::Inputs::StringInput
# for now, need to pass id or it won't work # for now, need to pass id or it won't work
def input(wrapper_options) def input(wrapper_options)
@ -16,12 +14,12 @@ class DeltaInput < SimpleForm::Inputs::StringInput
delta_button(content_tag(:i, nil, class: 'icon icon-plus'), 1, options) delta_button(content_tag(:i, nil, class: 'icon icon-plus'), 1, options)
end end
end end
#template.button_tag('', type: :submit, data: {decrement: options[:id]}, tabindex: -1, class: 'btn') + # template.button_tag('', type: :submit, data: {decrement: options[:id]}, tabindex: -1, class: 'btn') +
private private
def delta_button(title, direction, options) def delta_button(title, direction, options)
data = { (direction>0 ? 'increment' : 'decrement') => options[:id] } data = { (direction > 0 ? 'increment' : 'decrement') => options[:id] }
delta = direction * options[:data][:delta] delta = direction * options[:data][:delta]
template.button_tag(title, type: :button, name: 'delta', value: delta, data: data, tabindex: -1, class: 'btn') template.button_tag(title, type: :button, name: 'delta', value: delta, data: data, tabindex: -1, class: 'btn')
end end

View file

@ -1,5 +1,4 @@
class BounceMailReceiver class BounceMailReceiver
def self.regexp def self.regexp
/bounce\+(?<local>.*)=(?<domain>[^=]+)/ /bounce\+(?<local>.*)=(?<domain>[^=]+)/
end end
@ -16,5 +15,4 @@ class BounceMailReceiver
attachment_mime: 'message/rfc822', attachment_mime: 'message/rfc822',
attachment_data: data attachment_data: data
end end
end end

View file

@ -1,4 +1,3 @@
# encoding: utf-8
# ActionMailer class that handles all emails for Foodsoft. # ActionMailer class that handles all emails for Foodsoft.
class Mailer < ActionMailer::Base class Mailer < ActionMailer::Base
# XXX Quick fix to allow the use of show_user. Proper take would be one of # XXX Quick fix to allow the use of show_user. Proper take would be one of
@ -7,7 +6,7 @@ class Mailer < ActionMailer::Base
helper :application helper :application
include ApplicationHelper include ApplicationHelper
layout 'email' # Use views/layouts/email.txt.erb layout 'email' # Use views/layouts/email.txt.erb
default from: "#{I18n.t('layouts.foodsoft')} <#{FoodsoftConfig[:email_sender]}>", default from: "#{I18n.t('layouts.foodsoft')} <#{FoodsoftConfig[:email_sender]}>",
'X-Auto-Response-Suppress' => 'All' 'X-Auto-Response-Suppress' => 'All'
@ -71,7 +70,7 @@ class Mailer < ActionMailer::Base
@scarce_articles = order_articles.select { |oa| oa.difference_received_ordered.negative? } @scarce_articles = order_articles.select { |oa| oa.difference_received_ordered.negative? }
mail to: user, mail to: user,
subject: I18n.t('mailer.order_received.subject', name: group_order.order.name) subject: I18n.t('mailer.order_received.subject', name: group_order.order.name)
end end
# Sends order result to the supplier # Sends order result to the supplier
@ -92,7 +91,7 @@ class Mailer < ActionMailer::Base
end end
# Notify user if account balance is less than zero # Notify user if account balance is less than zero
def negative_balance(user,transaction) def negative_balance(user, transaction)
@group = user.ordergroup @group = user.ordergroup
@transaction = transaction @transaction = transaction
@ -180,5 +179,4 @@ class Mailer < ActionMailer::Base
address.display_name = name address.display_name = name
address.format address.format
end end
end end

View file

@ -1,4 +1,3 @@
# encoding: utf-8
class Article < ApplicationRecord class Article < ApplicationRecord
include PriceCalculation include PriceCalculation
@ -66,8 +65,8 @@ class Article < ApplicationRecord
validates_numericality_of :price, :greater_than_or_equal_to => 0 validates_numericality_of :price, :greater_than_or_equal_to => 0
validates_numericality_of :unit_quantity, :greater_than => 0 validates_numericality_of :unit_quantity, :greater_than => 0
validates_numericality_of :deposit, :tax validates_numericality_of :deposit, :tax
#validates_uniqueness_of :name, :scope => [:supplier_id, :deleted_at, :type], if: Proc.new {|a| a.supplier.shared_sync_method.blank? or a.supplier.shared_sync_method == 'import' } # validates_uniqueness_of :name, :scope => [:supplier_id, :deleted_at, :type], if: Proc.new {|a| a.supplier.shared_sync_method.blank? or a.supplier.shared_sync_method == 'import' }
#validates_uniqueness_of :name, :scope => [:supplier_id, :deleted_at, :type, :unit, :unit_quantity] # validates_uniqueness_of :name, :scope => [:supplier_id, :deleted_at, :type, :unit, :unit_quantity]
validate :uniqueness_of_name validate :uniqueness_of_name
# Callbacks # Callbacks
@ -91,7 +90,7 @@ class Article < ApplicationRecord
def in_open_order def in_open_order
@in_open_order ||= begin @in_open_order ||= begin
order_articles = OrderArticle.where(order_id: Order.open.collect(&:id)) order_articles = OrderArticle.where(order_id: Order.open.collect(&:id))
order_article = order_articles.detect {|oa| oa.article_id == id } order_article = order_articles.detect { |oa| oa.article_id == id }
order_article ? order_article.order : nil order_article ? order_article.order : nil
end end
end end
@ -124,7 +123,7 @@ class Article < ApplicationRecord
# @param new_article [Article] New article to update self # @param new_article [Article] New article to update self
# @option options [Boolean] :convert_units Omit or set to +true+ to keep current unit and recompute unit quantity and price. # @option options [Boolean] :convert_units Omit or set to +true+ to keep current unit and recompute unit quantity and price.
# @return [Hash<Symbol, Object>] Attributes with new values # @return [Hash<Symbol, Object>] Attributes with new values
def unequal_attributes(new_article, options={}) def unequal_attributes(new_article, options = {})
# try to convert different units when desired # try to convert different units when desired
if options[:convert_units] == false if options[:convert_units] == false
new_price, new_unit_quantity = nil, nil new_price, new_unit_quantity = nil, nil
@ -162,7 +161,7 @@ class Article < ApplicationRecord
# @return [Hash<Symbol, Object>] Changed attributes with new values # @return [Hash<Symbol, Object>] Changed attributes with new values
def self.compare_attributes(attributes) def self.compare_attributes(attributes)
unequal_attributes = attributes.select { |name, values| values[0] != values[1] && !(values[0].blank? && values[1].blank?) } unequal_attributes = attributes.select { |name, values| values[0] != values[1] && !(values[0].blank? && values[1].blank?) }
Hash[unequal_attributes.to_a.map {|a| [a[0], a[1].last]}] Hash[unequal_attributes.to_a.map { |a| [a[0], a[1].last] }]
end end
# to get the correspondent shared article # to get the correspondent shared article
@ -183,7 +182,7 @@ class Article < ApplicationRecord
# try to match the size out of its name, e.g. "banana 10-12 St" => 10 # try to match the size out of its name, e.g. "banana 10-12 St" => 10
new_unit_quantity = /[0-9\-\s]+(St)/.match(new_article.name).to_s.to_i new_unit_quantity = /[0-9\-\s]+(St)/.match(new_article.name).to_s.to_i
if new_unit_quantity && new_unit_quantity > 0 if new_unit_quantity && new_unit_quantity > 0
new_price = (new_article.price/new_unit_quantity.to_f).round(2) new_price = (new_article.price / new_unit_quantity.to_f).round(2)
[new_price, new_unit_quantity] [new_price, new_unit_quantity]
else else
false false
@ -250,5 +249,4 @@ class Article < ApplicationRecord
errors.add :name, :taken_with_unit if matches.where(unit: unit, unit_quantity: unit_quantity).any? errors.add :name, :taken_with_unit if matches.where(unit: unit, unit_quantity: unit_quantity).any?
end end
end end
end end

View file

@ -1,6 +1,5 @@
# Article category # Article category
class ArticleCategory < ApplicationRecord class ArticleCategory < ApplicationRecord
# @!attribute name # @!attribute name
# @return [String] Title of the category. # @return [String] Title of the category.
# @!attrubute description # @!attrubute description
@ -34,15 +33,16 @@ class ArticleCategory < ApplicationRecord
# TODO more intelligence like remembering earlier associations (global and/or per-supplier) # TODO more intelligence like remembering earlier associations (global and/or per-supplier)
def self.find_match(category) def self.find_match(category)
return if category.blank? || category.length < 3 return if category.blank? || category.length < 3
c = nil c = nil
## exact match - not needed, will be returned by next query as well ## exact match - not needed, will be returned by next query as well
#c ||= ArticleCategory.where(name: category).first # c ||= ArticleCategory.where(name: category).first
# case-insensitive substring match (take the closest match = shortest) # case-insensitive substring match (take the closest match = shortest)
c = ArticleCategory.where('name LIKE ?', "%#{category}%") unless c && c.any? c = ArticleCategory.where('name LIKE ?', "%#{category}%") unless c && c.any?
# case-insensitive phrase present in category description # case-insensitive phrase present in category description
c = ArticleCategory.where('description LIKE ?', "%#{category}%").select {|s| s.description.match /(^|,)\s*#{category}\s*(,|$)/i} unless c && c.any? c = ArticleCategory.where('description LIKE ?', "%#{category}%").select { |s| s.description.match /(^|,)\s*#{category}\s*(,|$)/i } unless c && c.any?
# return closest match if there are multiple # return closest match if there are multiple
c = c.sort_by {|s| s.name.length}.first if c.respond_to? :sort_by c = c.sort_by { |s| s.name.length }.first if c.respond_to? :sort_by
c c
end end
@ -52,5 +52,4 @@ class ArticleCategory < ApplicationRecord
def check_for_associated_articles def check_for_associated_articles
raise I18n.t('activerecord.errors.has_many_left', collection: Article.model_name.human) if articles.undeleted.exists? raise I18n.t('activerecord.errors.has_many_left', collection: Article.model_name.human) if articles.undeleted.exists?
end end
end end

View file

@ -27,5 +27,4 @@ class ArticlePrice < ApplicationRecord
validates_numericality_of :price, :greater_than_or_equal_to => 0 validates_numericality_of :price, :greater_than_or_equal_to => 0
validates_numericality_of :unit_quantity, :greater_than => 0 validates_numericality_of :unit_quantity, :greater_than => 0
validates_numericality_of :deposit, :tax validates_numericality_of :deposit, :tax
end end

View file

@ -1,5 +1,4 @@
class Assignment < ApplicationRecord class Assignment < ApplicationRecord
belongs_to :user belongs_to :user
belongs_to :task belongs_to :task
end end

View file

@ -1,5 +1,4 @@
class BankAccount < ApplicationRecord class BankAccount < ApplicationRecord
has_many :bank_transactions, dependent: :destroy has_many :bank_transactions, dependent: :destroy
normalize_attributes :name, :iban, :description normalize_attributes :name, :iban, :description

View file

@ -1,5 +1,4 @@
class BankTransaction < ApplicationRecord class BankTransaction < ApplicationRecord
# @!attribute external_id # @!attribute external_id
# @return [String] Unique Identifier of the transaction within the bank account. # @return [String] Unique Identifier of the transaction within the bank account.
# @!attribute date # @!attribute date
@ -39,13 +38,13 @@ class BankTransaction < ApplicationRecord
content = text content = text
content += "\n" + reference if reference.present? content += "\n" + reference if reference.present?
invoices = supplier.invoices.unpaid.select {|i| content.include? i.number} invoices = supplier.invoices.unpaid.select { |i| content.include? i.number }
invoices_sum = invoices.map(&:amount).sum invoices_sum = invoices.map(&:amount).sum
return false if amount != -invoices_sum return false if amount != -invoices_sum
transaction do transaction do
link = FinancialLink.new link = FinancialLink.new
invoices.each {|i| i.update_attributes! financial_link: link, paid_on: date } invoices.each { |i| i.update_attributes! financial_link: link, paid_on: date }
update_attribute :financial_link, link update_attribute :financial_link, link
end end
@ -57,8 +56,10 @@ class BankTransaction < ApplicationRecord
return unless m return unless m
return false if m[:parts].values.sum != amount return false if m[:parts].values.sum != amount
group = Ordergroup.find_by_id(m[:group]) group = Ordergroup.find_by_id(m[:group])
return false unless group return false unless group
usr = m[:user] ? User.find_by_id(m[:user]) : group.users.first usr = m[:user] ? User.find_by_id(m[:user]) : group.users.first
return false unless usr return false unless usr
@ -69,6 +70,7 @@ class BankTransaction < ApplicationRecord
m[:parts].each do |short, value| m[:parts].each do |short, value|
ftt = FinancialTransactionType.find_by_name_short(short) ftt = FinancialTransactionType.find_by_name_short(short)
return false unless ftt return false unless ftt
group.add_financial_transaction! value, note, usr, ftt, link if value > 0 group.add_financial_transaction! value, note, usr, ftt, link if value > 0
end end

View file

@ -6,7 +6,7 @@ module CustomFields
included do included do
after_initialize do after_initialize do
settings.defaults['custom_fields'] = { } unless settings.custom_fields settings.defaults['custom_fields'] = {} unless settings.custom_fields
end end
after_save do after_save do

View file

@ -3,7 +3,6 @@ module FindEachWithOrder
extend ActiveSupport::Concern extend ActiveSupport::Concern
class_methods do class_methods do
def find_each_with_order(options = {}) def find_each_with_order(options = {})
find_in_batches_with_order(options) do |records| find_in_batches_with_order(options) do |records|
records.each { |record| yield record } records.each { |record| yield record }
@ -34,6 +33,5 @@ module FindEachWithOrder
records = relation.offset(start).to_a records = relation.offset(start).to_a
end end
end end
end end
end end

View file

@ -12,7 +12,7 @@ module MarkAsDeletedWithName
n = '' n = ''
begin begin
append = " \u2020" + n append = " \u2020" + n
deleted_name = name.truncate(max_length-append.length, omission: '') + append deleted_name = name.truncate(max_length - append.length, omission: '') + append
if n.blank? if n.blank?
n = 'A' n = 'A'
else else

View file

@ -1,5 +1,4 @@
class Delivery < StockEvent class Delivery < StockEvent
belongs_to :supplier belongs_to :supplier
belongs_to :invoice, optional: true belongs_to :invoice, optional: true
@ -17,7 +16,7 @@ class Delivery < StockEvent
end end
def includes_article?(article) def includes_article?(article)
self.stock_changes.map{|stock_change| stock_change.stock_article.id}.include? article.id self.stock_changes.map { |stock_change| stock_change.stock_article.id }.include? article.id
end end
def sum(type = :gross) def sum(type = :gross)
@ -26,12 +25,12 @@ class Delivery < StockEvent
article = sc.stock_article article = sc.stock_article
quantity = sc.quantity quantity = sc.quantity
case type case type
when :net when :net
total += quantity * article.price total += quantity * article.price
when :gross when :gross
total += quantity * article.gross_price total += quantity * article.gross_price
when :fc when :fc
total += quantity * article.fc_price total += quantity * article.fc_price
end end
end end
total total
@ -40,9 +39,8 @@ class Delivery < StockEvent
protected protected
def stock_articles_must_be_unique def stock_articles_must_be_unique
unless stock_changes.reject{|sc| sc.marked_for_destruction?}.map {|sc| sc.stock_article.id}.uniq!.nil? unless stock_changes.reject { |sc| sc.marked_for_destruction? }.map { |sc| sc.stock_article.id }.uniq!.nil?
errors.add(:base, I18n.t('model.delivery.each_stock_article_must_be_unique')) errors.add(:base, I18n.t('model.delivery.each_stock_article_must_be_unique'))
end end
end end
end end

View file

@ -8,7 +8,7 @@ class FinancialLink < ApplicationRecord
includes(:bank_transactions, :financial_transactions, :invoices) includes(:bank_transactions, :financial_transactions, :invoices)
.where(bank_transactions: { financial_link_id: nil }) .where(bank_transactions: { financial_link_id: nil })
.where(financial_transactions: { financial_link_id: nil }) .where(financial_transactions: { financial_link_id: nil })
.where(invoices: { financial_link_id: nil}) .where(invoices: { financial_link_id: nil })
} }
scope :with_full_sum, -> { scope :with_full_sum, -> {
select(:id, :note, :full_sum).joins(<<-SQL) select(:id, :note, :full_sum).joins(<<-SQL)

View file

@ -11,7 +11,7 @@ class FinancialTransaction < ApplicationRecord
validates_presence_of :amount, :note, :user_id validates_presence_of :amount, :note, :user_id
validates_numericality_of :amount, greater_then: -100_000, validates_numericality_of :amount, greater_then: -100_000,
less_than: 100_000 less_than: 100_000
scope :visible, -> { joins('LEFT JOIN financial_transactions r ON financial_transactions.id = r.reverts_id').where('r.id IS NULL').where(reverts: nil) } scope :visible, -> { joins('LEFT JOIN financial_transactions r ON financial_transactions.id = r.reverts_id').where('r.id IS NULL').where(reverts: nil) }
scope :without_financial_link, -> { where(financial_link: nil) } scope :without_financial_link, -> { where(financial_link: nil) }

View file

@ -1,4 +1,3 @@
# encoding: utf-8
# Groups organize the User. # Groups organize the User.
# A Member gets the roles from the Group # A Member gets the roles from the Group
class Group < ApplicationRecord class Group < ApplicationRecord
@ -8,7 +7,7 @@ class Group < ApplicationRecord
has_many :memberships, dependent: :destroy has_many :memberships, dependent: :destroy
has_many :users, -> { where(deleted_at: nil) }, through: :memberships has_many :users, -> { where(deleted_at: nil) }, through: :memberships
validates :name, :presence => true, :length => {:in => 1..25} validates :name, :presence => true, :length => { :in => 1..25 }
validates_uniqueness_of :name validates_uniqueness_of :name
attr_reader :user_tokens attr_reader :user_tokens

View file

@ -13,7 +13,7 @@ class GroupOrder < ApplicationRecord
validates_presence_of :order_id validates_presence_of :order_id
validates_numericality_of :price validates_numericality_of :price
validates_uniqueness_of :ordergroup_id, :scope => :order_id # order groups can only order once per order validates_uniqueness_of :ordergroup_id, :scope => :order_id # order groups can only order once per order
scope :in_open_orders, -> { joins(:order).merge(Order.open) } scope :in_open_orders, -> { joins(:order).merge(Order.open) }
scope :in_finished_orders, -> { joins(:order).merge(Order.finished_not_closed) } scope :in_finished_orders, -> { joins(:order).merge(Order.finished_not_closed) }
@ -39,23 +39,22 @@ class GroupOrder < ApplicationRecord
data[:order_articles] = {} data[:order_articles] = {}
order.articles_grouped_by_category.each do |article_category, order_articles| order.articles_grouped_by_category.each do |article_category, order_articles|
order_articles.each do |order_article| order_articles.each do |order_article|
# Get the result of last time ordering, if possible # Get the result of last time ordering, if possible
goa = group_order_articles.detect { |goa| goa.order_article_id == order_article.id } goa = group_order_articles.detect { |goa| goa.order_article_id == order_article.id }
# Build hash with relevant data # Build hash with relevant data
data[:order_articles][order_article.id] = { data[:order_articles][order_article.id] = {
:price => order_article.article.fc_price, :price => order_article.article.fc_price,
:unit => order_article.article.unit_quantity, :unit => order_article.article.unit_quantity,
:quantity => (goa ? goa.quantity : 0), :quantity => (goa ? goa.quantity : 0),
:others_quantity => order_article.quantity - (goa ? goa.quantity : 0), :others_quantity => order_article.quantity - (goa ? goa.quantity : 0),
:used_quantity => (goa ? goa.result(:quantity) : 0), :used_quantity => (goa ? goa.result(:quantity) : 0),
:tolerance => (goa ? goa.tolerance : 0), :tolerance => (goa ? goa.tolerance : 0),
:others_tolerance => order_article.tolerance - (goa ? goa.tolerance : 0), :others_tolerance => order_article.tolerance - (goa ? goa.tolerance : 0),
:used_tolerance => (goa ? goa.result(:tolerance) : 0), :used_tolerance => (goa ? goa.result(:tolerance) : 0),
:total_price => (goa ? goa.total_price : 0), :total_price => (goa ? goa.total_price : 0),
:missing_units => order_article.missing_units, :missing_units => order_article.missing_units,
:quantity_available => (order.stockit? ? order_article.article.quantity_available : 0) :quantity_available => (order.stockit? ? order_article.article.quantity_available : 0)
} }
end end
end end
@ -70,7 +69,7 @@ class GroupOrder < ApplicationRecord
# Get ordered quantities and update group_order_articles/_quantities... # Get ordered quantities and update group_order_articles/_quantities...
if group_order_articles_attributes if group_order_articles_attributes
quantities = group_order_articles_attributes.fetch(order_article.id.to_s, {:quantity => 0, :tolerance => 0}) quantities = group_order_articles_attributes.fetch(order_article.id.to_s, { :quantity => 0, :tolerance => 0 })
group_order_article.update_quantities(quantities[:quantity].to_i, quantities[:tolerance].to_i) group_order_article.update_quantities(quantities[:quantity].to_i, quantities[:tolerance].to_i)
end end
@ -88,7 +87,6 @@ class GroupOrder < ApplicationRecord
update_attribute(:price, total) update_attribute(:price, total)
end end
# Save GroupOrder and updates group_order_articles/quantities accordingly # Save GroupOrder and updates group_order_articles/quantities accordingly
def save_ordering! def save_ordering!
transaction do transaction do
@ -104,7 +102,7 @@ class GroupOrder < ApplicationRecord
def total def total
return price + transport if transport return price + transport if transport
price price
end end
end end

View file

@ -2,13 +2,12 @@
# The chronologically order of the Ordergroup - activity are stored in GroupOrderArticleQuantity # The chronologically order of the Ordergroup - activity are stored in GroupOrderArticleQuantity
# #
class GroupOrderArticle < ApplicationRecord class GroupOrderArticle < ApplicationRecord
belongs_to :group_order belongs_to :group_order
belongs_to :order_article belongs_to :order_article
has_many :group_order_article_quantities, dependent: :destroy has_many :group_order_article_quantities, dependent: :destroy
validates_presence_of :group_order, :order_article validates_presence_of :group_order, :order_article
validates_uniqueness_of :order_article_id, :scope => :group_order_id # just once an article per group order validates_uniqueness_of :order_article_id, :scope => :group_order_id # just once an article per group order
validate :check_order_not_closed # don't allow changes to closed (aka settled) orders validate :check_order_not_closed # don't allow changes to closed (aka settled) orders
validates :quantity, :tolerance, numericality: { only_integer: true, greater_than_or_equal_to: 0 } validates :quantity, :tolerance, numericality: { only_integer: true, greater_than_or_equal_to: 0 }
@ -83,10 +82,10 @@ class GroupOrderArticle < ApplicationRecord
if (quantity > self.quantity || tolerance > self.tolerance) if (quantity > self.quantity || tolerance > self.tolerance)
logger.debug("Inserting a new GroupOrderArticleQuantity") logger.debug("Inserting a new GroupOrderArticleQuantity")
quantities.insert(0, GroupOrderArticleQuantity.new( quantities.insert(0, GroupOrderArticleQuantity.new(
:group_order_article => self, :group_order_article => self,
:quantity => (quantity > self.quantity ? quantity - self.quantity : 0), :quantity => (quantity > self.quantity ? quantity - self.quantity : 0),
:tolerance => (tolerance > self.tolerance ? tolerance - self.tolerance : 0) :tolerance => (tolerance > self.tolerance ? tolerance - self.tolerance : 0)
)) ))
# Recalc totals: # Recalc totals:
self.quantity += quantities[0].quantity self.quantity += quantities[0].quantity
self.tolerance += quantities[0].tolerance self.tolerance += quantities[0].tolerance
@ -99,11 +98,11 @@ class GroupOrderArticle < ApplicationRecord
end end
# Remove zero-only items. # Remove zero-only items.
quantities = quantities.reject { | q | q.quantity == 0 && q.tolerance == 0} quantities = quantities.reject { |q| q.quantity == 0 && q.tolerance == 0 }
# Save # Save
transaction do transaction do
quantities.each { | i | i.save! } quantities.each { |i| i.save! }
self.group_order_article_quantities = quantities self.group_order_article_quantities = quantities
save! save!
end end
@ -169,7 +168,7 @@ class GroupOrderArticle < ApplicationRecord
end end
# memoize result unless a total is given # memoize result unless a total is given
r = {:quantity => quantity, :tolerance => tolerance, :total => quantity + tolerance} r = { :quantity => quantity, :tolerance => tolerance, :total => quantity + tolerance }
@calculate_result = r if total.nil? @calculate_result = r if total.nil?
r r
end end

View file

@ -2,7 +2,6 @@
# Considers every update of an article-order, so may rows for one group_order_article ar possible. # Considers every update of an article-order, so may rows for one group_order_article ar possible.
class GroupOrderArticleQuantity < ApplicationRecord class GroupOrderArticleQuantity < ApplicationRecord
belongs_to :group_order_article belongs_to :group_order_article
validates_presence_of :group_order_article_id validates_presence_of :group_order_article_id

View file

@ -14,7 +14,7 @@ class Invite < ApplicationRecord
before_validation :set_token_and_expires_at before_validation :set_token_and_expires_at
protected protected
# Before validation, set token and expires_at. # Before validation, set token and expires_at.
def set_token_and_expires_at def set_token_and_expires_at
@ -22,7 +22,7 @@ class Invite < ApplicationRecord
self.expires_at = Time.now.advance(:days => 7) self.expires_at = Time.now.advance(:days => 7)
end end
private private
# Custom validation: check that email does not already belong to a registered user. # Custom validation: check that email does not already belong to a registered user.
def email_not_already_registered def email_not_already_registered
@ -30,5 +30,4 @@ class Invite < ApplicationRecord
errors.add(:email, I18n.t('invites.errors.already_member')) errors.add(:email, I18n.t('invites.errors.already_member'))
end end
end end
end end

View file

@ -1,11 +1,9 @@
class Membership < ApplicationRecord class Membership < ApplicationRecord
belongs_to :user belongs_to :user
belongs_to :group belongs_to :group
before_destroy :check_last_admin before_destroy :check_last_admin
protected protected
# check if this is the last admin-membership and deny # check if this is the last admin-membership and deny

View file

@ -1,5 +1,3 @@
# encoding: utf-8
#
class Order < ApplicationRecord class Order < ApplicationRecord
attr_accessor :ignore_warnings, :transport_distribution attr_accessor :ignore_warnings, :transport_distribution
@ -71,8 +69,8 @@ class Order < ApplicationRecord
if stockit? if stockit?
# make sure to include those articles which are no longer available # make sure to include those articles which are no longer available
# but which have already been ordered in this stock order # but which have already been ordered in this stock order
StockArticle.available.includes(:article_category). StockArticle.available.includes(:article_category)
order('article_categories.name', 'articles.name').reject{ |a| .order('article_categories.name', 'articles.name').reject { |a|
a.quantity_available <= 0 && !a.ordered_in_order?(self) a.quantity_available <= 0 && !a.ordered_in_order?(self)
}.group_by { |a| a.article_category.name } }.group_by { |a| a.article_category.name }
else else
@ -151,7 +149,7 @@ class Order < ApplicationRecord
def self.ordergroup_group_orders_map(ordergroup) def self.ordergroup_group_orders_map(ordergroup)
orders = includes(:supplier) orders = includes(:supplier)
group_orders = GroupOrder.where(ordergroup_id: ordergroup.id, order_id: orders.map(&:id)) group_orders = GroupOrder.where(ordergroup_id: ordergroup.id, order_id: orders.map(&:id))
group_orders_hash = Hash[group_orders.collect {|go| [go.order_id, go]}] group_orders_hash = Hash[group_orders.collect { |go| [go.order_id, go] }]
orders.map do |order| orders.map do |order|
{ {
order: order, order: order,
@ -173,22 +171,22 @@ class Order < ApplicationRecord
# The array has the following form: # The array has the following form:
# e.g: [["drugs",[teethpaste, toiletpaper]], ["fruits" => [apple, banana, lemon]]] # e.g: [["drugs",[teethpaste, toiletpaper]], ["fruits" => [apple, banana, lemon]]]
def articles_grouped_by_category def articles_grouped_by_category
@articles_grouped_by_category ||= order_articles. @articles_grouped_by_category ||= order_articles
includes([:article_price, :group_order_articles, :article => :article_category]). .includes([:article_price, :group_order_articles, :article => :article_category])
order('articles.name'). .order('articles.name')
group_by { |a| a.article.article_category.name }. .group_by { |a| a.article.article_category.name }
sort { |a, b| a[0] <=> b[0] } .sort { |a, b| a[0] <=> b[0] }
end end
def articles_sort_by_category def articles_sort_by_category
order_articles.includes(:article).order('articles.name').sort do |a,b| order_articles.includes(:article).order('articles.name').sort do |a, b|
a.article.article_category.name <=> b.article.article_category.name a.article.article_category.name <=> b.article.article_category.name
end end
end end
# Returns the defecit/benefit for the foodcoop # Returns the defecit/benefit for the foodcoop
# Requires a valid invoice, belonging to this order # Requires a valid invoice, belonging to this order
#FIXME: Consider order.foodcoop_result # FIXME: Consider order.foodcoop_result
def profit(options = {}) def profit(options = {})
markup = options[:without_markup] || false markup = options[:without_markup] || false
if invoice if invoice
@ -208,22 +206,22 @@ class Order < ApplicationRecord
for oa in order_articles.ordered.includes(:article, :article_price) for oa in order_articles.ordered.includes(:article, :article_price)
quantity = oa.units * oa.price.unit_quantity quantity = oa.units * oa.price.unit_quantity
case type case type
when :net when :net
total += quantity * oa.price.price total += quantity * oa.price.price
when :gross when :gross
total += quantity * oa.price.gross_price total += quantity * oa.price.gross_price
when :fc when :fc
total += quantity * oa.price.fc_price total += quantity * oa.price.fc_price
end end
end end
elsif type == :groups || type == :groups_without_markup elsif type == :groups || type == :groups_without_markup
for go in group_orders.includes(group_order_articles: {order_article: [:article, :article_price]}) for go in group_orders.includes(group_order_articles: { order_article: [:article, :article_price] })
for goa in go.group_order_articles for goa in go.group_order_articles
case type case type
when :groups when :groups
total += goa.result * goa.order_article.price.fc_price total += goa.result * goa.order_article.price.fc_price
when :groups_without_markup when :groups_without_markup
total += goa.result * goa.order_article.price.gross_price total += goa.result * goa.order_article.price.gross_price
end end
end end
end end
@ -251,7 +249,7 @@ class Order < ApplicationRecord
# A: Yes, we do - for redistributing articles when the number of articles # A: Yes, we do - for redistributing articles when the number of articles
# delivered changes, and for statistics on popular articles. Records # delivered changes, and for statistics on popular articles. Records
# with both tolerance and quantity zero can be deleted. # with both tolerance and quantity zero can be deleted.
#goa.group_order_article_quantities.clear # goa.group_order_article_quantities.clear
end end
end end
@ -279,7 +277,7 @@ class Order < ApplicationRecord
if stockit? # Decreases the quantity of stock_articles if stockit? # Decreases the quantity of stock_articles
for oa in order_articles.includes(:article) for oa in order_articles.includes(:article)
oa.update_results! # Update units_to_order of order_article oa.update_results! # Update units_to_order of order_article
stock_changes.create! :stock_article => oa.article, :quantity => oa.units_to_order*-1 stock_changes.create! :stock_article => oa.article, :quantity => oa.units_to_order * -1
end end
end end
@ -290,6 +288,7 @@ class Order < ApplicationRecord
# Close the order directly, without automaticly updating ordergroups account balances # Close the order directly, without automaticly updating ordergroups account balances
def close_direct!(user) def close_direct!(user)
raise I18n.t('orders.model.error_closed') if closed? raise I18n.t('orders.model.error_closed') if closed?
comments.create(user: user, text: I18n.t('orders.model.close_direct_message')) unless FoodsoftConfig[:charge_members_manually] comments.create(user: user, text: I18n.t('orders.model.close_direct_message')) unless FoodsoftConfig[:charge_members_manually]
update_attributes! state: 'closed', updated_by: user update_attributes! state: 'closed', updated_by: user
end end
@ -319,7 +318,7 @@ class Order < ApplicationRecord
begin begin
order.do_end_action! order.do_end_action!
rescue => error rescue => error
ExceptionNotifier.notify_exception(error, data: {foodcoop: FoodsoftConfig.scope, order_id: order.id}) ExceptionNotifier.notify_exception(error, data: { foodcoop: FoodsoftConfig.scope, order_id: order.id })
end end
end end
end end
@ -328,9 +327,9 @@ class Order < ApplicationRecord
def starts_before_ends def starts_before_ends
delta = Rails.env.test? ? 1 : 0 # since Rails 4.2 tests appear to have time differences, with this validation failing delta = Rails.env.test? ? 1 : 0 # since Rails 4.2 tests appear to have time differences, with this validation failing
errors.add(:ends, I18n.t('orders.model.error_starts_before_ends')) if ends && starts && ends <= (starts-delta) errors.add(:ends, I18n.t('orders.model.error_starts_before_ends')) if ends && starts && ends <= (starts - delta)
errors.add(:ends, I18n.t('orders.model.error_boxfill_before_ends')) if ends && boxfill && ends <= (boxfill-delta) errors.add(:ends, I18n.t('orders.model.error_boxfill_before_ends')) if ends && boxfill && ends <= (boxfill - delta)
errors.add(:boxfill, I18n.t('orders.model.error_starts_before_boxfill')) if boxfill && starts && boxfill <= (starts-delta) errors.add(:boxfill, I18n.t('orders.model.error_starts_before_boxfill')) if boxfill && starts && boxfill <= (starts - delta)
end end
def include_articles def include_articles
@ -362,6 +361,7 @@ class Order < ApplicationRecord
def distribute_transport def distribute_transport
return unless group_orders.any? return unless group_orders.any?
case transport_distribution.try(&:to_i) case transport_distribution.try(&:to_i)
when Order.transport_distributions[:ordergroup] then when Order.transport_distributions[:ordergroup] then
amount = transport / group_orders.size amount = transport / group_orders.size

View file

@ -38,6 +38,7 @@ class OrderArticle < ApplicationRecord
def units def units
return units_received unless units_received.nil? return units_received unless units_received.nil?
return units_billed unless units_billed.nil? return units_billed unless units_billed.nil?
units_to_order units_to_order
end end
@ -45,7 +46,7 @@ class OrderArticle < ApplicationRecord
# In balancing this can differ from ordered (by supplier) quantity for this article. # In balancing this can differ from ordered (by supplier) quantity for this article.
def group_orders_sum def group_orders_sum
quantity = group_order_articles.collect(&:result).sum quantity = group_order_articles.collect(&:result).sum
{:quantity => quantity, :price => quantity * price.fc_price} { :quantity => quantity, :price => quantity * price.fc_price }
end end
# Update quantity/tolerance/units_to_order from group_order_articles # Update quantity/tolerance/units_to_order from group_order_articles
@ -96,7 +97,7 @@ class OrderArticle < ApplicationRecord
units * price.unit_quantity * price.gross_price units * price.unit_quantity * price.gross_price
end end
def ordered_quantities_different_from_group_orders?(ordered_mark="!", billed_mark="?", received_mark="?") def ordered_quantities_different_from_group_orders?(ordered_mark = "!", billed_mark = "?", received_mark = "?")
if not units_received.nil? if not units_received.nil?
((units_received * price.unit_quantity) == group_orders_sum[:quantity]) ? false : received_mark ((units_received * price.unit_quantity) == group_orders_sum[:quantity]) ? false : received_mark
elsif not units_billed.nil? elsif not units_billed.nil?
@ -123,12 +124,12 @@ class OrderArticle < ApplicationRecord
if surplus.index(:tolerance).nil? if surplus.index(:tolerance).nil?
qty_for_members = [qty_left, self.quantity].min qty_for_members = [qty_left, self.quantity].min
else else
qty_for_members = [qty_left, self.quantity+self.tolerance].min qty_for_members = [qty_left, self.quantity + self.tolerance].min
counts[surplus.index(:tolerance)] = [0, qty_for_members-self.quantity].max counts[surplus.index(:tolerance)] = [0, qty_for_members - self.quantity].max
end end
# Recompute # Recompute
group_order_articles.each {|goa| goa.save_results! qty_for_members } group_order_articles.each { |goa| goa.save_results! qty_for_members }
qty_left -= qty_for_members qty_left -= qty_for_members
# if there's anything left, move to stock if wanted # if there's anything left, move to stock if wanted
@ -185,7 +186,7 @@ class OrderArticle < ApplicationRecord
end end
def update_global_price=(value) def update_global_price=(value)
@update_global_price = (value == true || value == '1') ? true : false @update_global_price = (value == true || value == '1') ? true : false
end end
# @return [Number] Units missing for the last +unit_quantity+ of the article. # @return [Number] Units missing for the last +unit_quantity+ of the article.
@ -199,7 +200,7 @@ class OrderArticle < ApplicationRecord
# Check if the result of any associated GroupOrderArticle was overridden manually # Check if the result of any associated GroupOrderArticle was overridden manually
def result_manually_changed? def result_manually_changed?
group_order_articles.any? {|goa| goa.result_manually_changed?} group_order_articles.any? { |goa| goa.result_manually_changed? }
end end
def difference_received_ordered def difference_received_ordered
@ -245,7 +246,7 @@ class OrderArticle < ApplicationRecord
end end
def _missing_units(unit_quantity, quantity, tolerance) def _missing_units(unit_quantity, quantity, tolerance)
units = unit_quantity - ((quantity % unit_quantity) + tolerance) units = unit_quantity - ((quantity % unit_quantity) + tolerance)
units = 0 if units < 0 units = 0 if units < 0
units = 0 if units == unit_quantity units = 0 if units == unit_quantity
units units

View file

@ -1,5 +1,4 @@
class OrderComment < ApplicationRecord class OrderComment < ApplicationRecord
belongs_to :order belongs_to :order
belongs_to :user belongs_to :user

View file

@ -1,13 +1,12 @@
# encoding: utf-8
# #
# Ordergroups can order, they are "children" of the class Group # Ordergroups can order, they are "children" of the class Group
# #
# Ordergroup have the following attributes, in addition to Group # Ordergroup have the following attributes, in addition to Group
# * account_balance (decimal) # * account_balance (decimal)
class Ordergroup < Group class Ordergroup < Group
include CustomFields include CustomFields
APPLE_MONTH_AGO = 6 # How many month back we will count tasks and orders sum APPLE_MONTH_AGO = 6 # How many month back we will count tasks and orders sum
serialize :stats serialize :stats
@ -24,6 +23,7 @@ class Ordergroup < Group
def contact def contact
"#{contact_phone} (#{contact_person})" "#{contact_phone} (#{contact_person})"
end end
def non_members def non_members
User.natural_order.all.reject { |u| (users.include?(u) || u.ordergroup) } User.natural_order.all.reject { |u| (users.include?(u) || u.ordergroup) }
end end
@ -43,6 +43,7 @@ class Ordergroup < Group
def self.custom_fields def self.custom_fields
fields = FoodsoftConfig[:custom_fields] && FoodsoftConfig[:custom_fields][:ordergroup] fields = FoodsoftConfig[:custom_fields] && FoodsoftConfig[:custom_fields][:ordergroup]
return [] unless fields return [] unless fields
fields.map(&:deep_symbolize_keys) fields.map(&:deep_symbolize_keys)
end end
@ -59,11 +60,11 @@ class Ordergroup < Group
end end
def value_of_open_orders(exclude = nil) def value_of_open_orders(exclude = nil)
group_orders.in_open_orders.reject{|go| go == exclude}.collect(&:price).sum group_orders.in_open_orders.reject { |go| go == exclude }.collect(&:price).sum
end end
def value_of_finished_orders(exclude = nil) def value_of_finished_orders(exclude = nil)
group_orders.in_finished_orders.reject{|go| go == exclude}.collect(&:price).sum group_orders.in_finished_orders.reject { |go| go == exclude }.collect(&:price).sum
end end
# Returns the available funds for this order group (the account_balance minus price of all non-closed GroupOrders of this group). # Returns the available funds for this order group (the account_balance minus price of all non-closed GroupOrders of this group).
@ -75,7 +76,7 @@ class Ordergroup < Group
def financial_transaction_class_balance(klass) def financial_transaction_class_balance(klass)
financial_transactions financial_transactions
.joins(:financial_transaction_type) .joins(:financial_transaction_type)
.where(financial_transaction_types: {financial_transaction_class_id: klass}) .where(financial_transaction_types: { financial_transaction_class_id: klass })
.sum(:amount) .sum(:amount)
end end
@ -101,14 +102,14 @@ class Ordergroup < Group
orders_sum = group_orders.includes(:order).merge(Order.finished).where('orders.ends >= ?', APPLE_MONTH_AGO.month.ago).references(:orders).sum(:price) orders_sum = group_orders.includes(:order).merge(Order.finished).where('orders.ends >= ?', APPLE_MONTH_AGO.month.ago).references(:orders).sum(:price)
@readonly = false # Dirty hack, avoid getting RecordReadOnly exception when called in task after_save callback. A rails bug? @readonly = false # Dirty hack, avoid getting RecordReadOnly exception when called in task after_save callback. A rails bug?
update_attribute(:stats, {:jobs_size => jobs, :orders_sum => orders_sum}) update_attribute(:stats, { :jobs_size => jobs, :orders_sum => orders_sum })
end end
def update_balance! def update_balance!
new_account_balance = financial_transactions new_account_balance = financial_transactions
.joins(financial_transaction_type: [:financial_transaction_class]) .joins(financial_transaction_type: [:financial_transaction_class])
.where({ financial_transaction_classes: { ignore_for_account_balance: false} }) .where({ financial_transaction_classes: { ignore_for_account_balance: false } })
.sum(:amount) .sum(:amount)
update_attribute :account_balance, new_account_balance update_attribute :account_balance, new_account_balance
end end
@ -116,7 +117,7 @@ class Ordergroup < Group
stats[:jobs_size].to_f / stats[:orders_sum].to_f rescue 0 stats[:jobs_size].to_f / stats[:orders_sum].to_f rescue 0
end end
# This is the ordergroup job per euro performance # This is the ordergroup job per euro performance
# in comparison to the hole foodcoop average # in comparison to the hole foodcoop average
def apples def apples
((avg_jobs_per_euro / Ordergroup.avg_jobs_per_euro) * 100).to_i rescue 0 ((avg_jobs_per_euro / Ordergroup.avg_jobs_per_euro) * 100).to_i rescue 0
@ -128,23 +129,23 @@ class Ordergroup < Group
# Only ordergroups, which have participated in more than 5 orders in total and more than 2 orders in apple time period # Only ordergroups, which have participated in more than 5 orders in total and more than 2 orders in apple time period
def not_enough_apples? def not_enough_apples?
FoodsoftConfig[:use_apple_points] && FoodsoftConfig[:use_apple_points] &&
FoodsoftConfig[:stop_ordering_under].present? && FoodsoftConfig[:stop_ordering_under].present? &&
!ignore_apple_restriction && !ignore_apple_restriction &&
apples < FoodsoftConfig[:stop_ordering_under] && apples < FoodsoftConfig[:stop_ordering_under] &&
group_orders.count > 5 && group_orders.count > 5 &&
group_orders.joins(:order).merge(Order.finished).where('orders.ends >= ?', APPLE_MONTH_AGO.month.ago).count > 2 group_orders.joins(:order).merge(Order.finished).where('orders.ends >= ?', APPLE_MONTH_AGO.month.ago).count > 2
end end
# Global average # Global average
def self.avg_jobs_per_euro def self.avg_jobs_per_euro
stats = Ordergroup.pluck(:stats) stats = Ordergroup.pluck(:stats)
stats.sum {|s| s[:jobs_size].to_f } / stats.sum {|s| s[:orders_sum].to_f } rescue 0 stats.sum { |s| s[:jobs_size].to_f } / stats.sum { |s| s[:orders_sum].to_f } rescue 0
end end
def account_updated def account_updated
financial_transactions.last.try(:created_on) || created_on financial_transactions.last.try(:created_on) || created_on
end end
private private
# Make sure, that a user can only be in one ordergroup # Make sure, that a user can only be in one ordergroup
@ -163,6 +164,4 @@ class Ordergroup < Group
errors.add :name, message errors.add :name, message
end end
end end
end end

View file

@ -4,6 +4,7 @@ class PeriodicTaskGroup < ApplicationRecord
def has_next_task? def has_next_task?
return false if tasks.empty? return false if tasks.empty?
return false if tasks.first.due_date.nil? return false if tasks.first.due_date.nil?
return true return true
end end

Some files were not shown because too many files have changed in this diff Show more