chore: rubocop
chore: fix api test conventions chore: rubocop -A spec/ chore: more rubocop -A fix failing test rubocop fixes removes helper methods that are in my opinion dead code more rubocop fixes rubocop -a --auto-gen-config
This commit is contained in:
parent
f6fb804bbe
commit
fb2b4d8a8a
331 changed files with 4263 additions and 4507 deletions
1829
.rubocop_todo.yml
1829
.rubocop_todo.yml
File diff suppressed because it is too large
Load diff
93
Gemfile
93
Gemfile
|
@ -1,75 +1,74 @@
|
||||||
# A sample Gemfile
|
# A sample Gemfile
|
||||||
source "https://rubygems.org"
|
source 'https://rubygems.org'
|
||||||
|
|
||||||
gem "rails", '~> 7.0'
|
|
||||||
gem 'mail', '~> 2.7.1' # bug with mail 2.8.0 https://github.com/mikel/mail/issues/1489
|
gem 'mail', '~> 2.7.1' # bug with mail 2.8.0 https://github.com/mikel/mail/issues/1489
|
||||||
|
gem 'rails', '~> 7.0'
|
||||||
|
|
||||||
|
|
||||||
gem 'sassc-rails'
|
|
||||||
gem 'less-rails'
|
gem 'less-rails'
|
||||||
|
gem 'sassc-rails'
|
||||||
gem 'uglifier'
|
gem 'uglifier'
|
||||||
# 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 'bootsnap', require: false
|
||||||
gem 'select2-rails'
|
|
||||||
gem 'rails_tokeninput'
|
|
||||||
gem 'bootstrap-datepicker-rails'
|
gem 'bootstrap-datepicker-rails'
|
||||||
gem 'date_time_attribute'
|
gem 'date_time_attribute'
|
||||||
gem 'rails-assets-listjs', '0.2.0.beta.4' # remember to maintain list.*.js plugins and template engines on update
|
|
||||||
gem 'i18n-js', '~> 3.0.0.rc8'
|
gem 'i18n-js', '~> 3.0.0.rc8'
|
||||||
|
gem 'jquery-rails'
|
||||||
|
gem 'rails-assets-listjs', '0.2.0.beta.4' # remember to maintain list.*.js plugins and template engines on update
|
||||||
gem 'rails-i18n'
|
gem 'rails-i18n'
|
||||||
gem 'bootsnap', require: false
|
gem 'rails_tokeninput'
|
||||||
|
gem 'select2-rails'
|
||||||
|
|
||||||
gem 'mysql2'
|
gem 'active_model_serializers', '~> 0.10.0'
|
||||||
gem 'prawn'
|
gem 'acts_as_tree'
|
||||||
gem 'prawn-table'
|
gem 'attribute_normalizer'
|
||||||
gem 'haml'
|
|
||||||
gem 'haml-rails'
|
|
||||||
gem 'kaminari'
|
|
||||||
gem 'simple_form'
|
|
||||||
gem 'inherited_resources'
|
|
||||||
gem 'daemons'
|
gem 'daemons'
|
||||||
gem 'doorkeeper'
|
gem 'doorkeeper'
|
||||||
gem 'doorkeeper-i18n'
|
gem 'doorkeeper-i18n'
|
||||||
|
gem 'haml'
|
||||||
|
gem 'haml-rails'
|
||||||
|
gem 'ice_cube'
|
||||||
|
gem 'inherited_resources'
|
||||||
|
gem 'kaminari'
|
||||||
|
gem 'mysql2'
|
||||||
|
gem 'prawn'
|
||||||
|
gem 'prawn-table'
|
||||||
|
gem 'puma'
|
||||||
gem 'rack-cors', require: 'rack/cors'
|
gem 'rack-cors', require: 'rack/cors'
|
||||||
gem 'active_model_serializers', '~> 0.10.0'
|
gem 'rails-settings-cached', '= 0.4.3' # caching breaks tests until Rails 5 https://github.com/huacnlee/rails-settings-cached/issues/73
|
||||||
gem 'twitter-bootstrap-rails', '~> 2.2.8'
|
gem 'ransack'
|
||||||
|
gem 'resque'
|
||||||
|
gem 'ruby-units'
|
||||||
|
gem 'sd_notify'
|
||||||
|
gem 'simple_form'
|
||||||
gem 'simple-navigation', '~> 3.14.0' # 3.x for simple_navigation_bootstrap
|
gem 'simple-navigation', '~> 3.14.0' # 3.x for simple_navigation_bootstrap
|
||||||
gem 'simple-navigation-bootstrap'
|
gem 'simple-navigation-bootstrap'
|
||||||
gem 'sprockets', '< 4'
|
gem 'sprockets', '< 4'
|
||||||
gem 'ransack'
|
gem 'twitter-bootstrap-rails', '~> 2.2.8'
|
||||||
gem 'acts_as_tree'
|
|
||||||
gem 'rails-settings-cached', '= 0.4.3' # caching breaks tests until Rails 5 https://github.com/huacnlee/rails-settings-cached/issues/73
|
|
||||||
gem 'resque'
|
|
||||||
gem 'puma'
|
|
||||||
gem 'sd_notify'
|
|
||||||
gem 'whenever', require: false # For defining cronjobs, see config/schedule.rb
|
gem 'whenever', require: false # For defining cronjobs, see config/schedule.rb
|
||||||
gem 'ruby-units'
|
|
||||||
gem 'attribute_normalizer'
|
|
||||||
gem 'ice_cube'
|
|
||||||
# At time of development 01-06-2022 mmddyyyy necessary fix for config_helper.rb form builder was not in rubygems so we pull from github, see: https://github.com/gregschmit/recurring_select/pull/152
|
# At time of development 01-06-2022 mmddyyyy necessary fix for config_helper.rb form builder was not in rubygems so we pull from github, see: https://github.com/gregschmit/recurring_select/pull/152
|
||||||
|
gem 'exception_notification'
|
||||||
|
gem 'gaffe'
|
||||||
|
gem 'hashie', '~> 3.4.6', require: false # https://github.com/westfieldlabs/apivore/issues/114
|
||||||
|
gem 'midi-smtp-server'
|
||||||
|
gem 'mime-types'
|
||||||
gem 'recurring_select', git: 'https://github.com/gregschmit/recurring_select'
|
gem 'recurring_select', git: 'https://github.com/gregschmit/recurring_select'
|
||||||
gem 'roo'
|
gem 'roo'
|
||||||
gem 'roo-xls'
|
gem 'roo-xls'
|
||||||
gem 'spreadsheet'
|
|
||||||
gem 'exception_notification'
|
|
||||||
gem 'gaffe'
|
|
||||||
gem 'ruby-filemagic'
|
|
||||||
gem 'mime-types'
|
|
||||||
gem 'midi-smtp-server'
|
|
||||||
gem 'hashie', '~> 3.4.6', require: false # https://github.com/westfieldlabs/apivore/issues/114
|
|
||||||
gem 'rswag-api'
|
gem 'rswag-api'
|
||||||
gem 'rswag-ui'
|
gem 'rswag-ui'
|
||||||
|
gem 'ruby-filemagic'
|
||||||
|
gem 'spreadsheet'
|
||||||
|
|
||||||
# we use the git version of acts_as_versioned, and need to include it in this Gemfile
|
# we use the git version of acts_as_versioned, and need to include it in this Gemfile
|
||||||
gem 'acts_as_versioned', git: 'https://github.com/technoweenie/acts_as_versioned.git'
|
gem 'acts_as_versioned', git: 'https://github.com/technoweenie/acts_as_versioned.git'
|
||||||
gem 'foodsoft_wiki', path: 'plugins/wiki'
|
|
||||||
gem 'foodsoft_messages', path: 'plugins/messages'
|
|
||||||
gem 'foodsoft_documents', path: 'plugins/documents'
|
|
||||||
gem 'foodsoft_discourse', path: 'plugins/discourse'
|
gem 'foodsoft_discourse', path: 'plugins/discourse'
|
||||||
|
gem 'foodsoft_documents', path: 'plugins/documents'
|
||||||
gem 'foodsoft_links', path: 'plugins/links'
|
gem 'foodsoft_links', path: 'plugins/links'
|
||||||
|
gem 'foodsoft_messages', path: 'plugins/messages'
|
||||||
gem 'foodsoft_polls', path: 'plugins/polls'
|
gem 'foodsoft_polls', path: 'plugins/polls'
|
||||||
|
gem 'foodsoft_wiki', path: 'plugins/wiki'
|
||||||
|
|
||||||
# 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'
|
||||||
|
@ -77,10 +76,10 @@ gem 'foodsoft_polls', path: 'plugins/polls'
|
||||||
# gem 'foodsoft_uservoice', path: 'plugins/uservoice'
|
# gem 'foodsoft_uservoice', path: 'plugins/uservoice'
|
||||||
|
|
||||||
group :development do
|
group :development do
|
||||||
gem 'sqlite3', '~> 1.3.6'
|
|
||||||
gem 'mailcatcher'
|
|
||||||
gem 'web-console'
|
|
||||||
gem 'listen'
|
gem 'listen'
|
||||||
|
gem 'mailcatcher'
|
||||||
|
gem 'sqlite3', '~> 1.3.6'
|
||||||
|
gem 'web-console'
|
||||||
|
|
||||||
# Better error output
|
# Better error output
|
||||||
gem 'better_errors'
|
gem 'better_errors'
|
||||||
|
@ -108,17 +107,17 @@ group :development, :test do
|
||||||
end
|
end
|
||||||
|
|
||||||
group :test do
|
group :test do
|
||||||
gem 'rspec-rails'
|
gem 'apparition' # Capybara javascript driver
|
||||||
|
gem 'capybara'
|
||||||
|
gem 'connection_pool'
|
||||||
|
gem 'database_cleaner'
|
||||||
gem 'factory_bot_rails'
|
gem 'factory_bot_rails'
|
||||||
gem 'faker'
|
gem 'faker'
|
||||||
gem 'capybara'
|
gem 'rspec-rails'
|
||||||
gem 'apparition' # Capybara javascript driver
|
|
||||||
gem 'database_cleaner'
|
|
||||||
gem 'connection_pool'
|
|
||||||
# need to include rspec components before i18n-spec or rake fails in test environment
|
# need to include rspec components before i18n-spec or rake fails in test environment
|
||||||
|
gem 'i18n-spec'
|
||||||
gem 'rspec-core'
|
gem 'rspec-core'
|
||||||
gem 'rspec-rerun'
|
gem 'rspec-rerun'
|
||||||
gem 'i18n-spec'
|
|
||||||
# code coverage
|
# code coverage
|
||||||
gem 'simplecov', require: false
|
gem 'simplecov', require: false
|
||||||
gem 'simplecov-lcov', require: false
|
gem 'simplecov-lcov', require: false
|
||||||
|
|
2
Rakefile
2
Rakefile
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env rake
|
#!/usr/bin/env rake
|
||||||
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
||||||
|
|
||||||
require File.expand_path('../config/application', __FILE__)
|
require File.expand_path('config/application', __dir__)
|
||||||
require 'rake'
|
require 'rake'
|
||||||
require 'rspec-rerun/tasks' if defined?(RSpec) # http://stackoverflow.com/a/16853615/2866660
|
require 'rspec-rerun/tasks' if defined?(RSpec) # http://stackoverflow.com/a/16853615/2866660
|
||||||
|
|
||||||
|
|
|
@ -3,39 +3,39 @@ class Admin::BankAccountsController < Admin::BaseController
|
||||||
|
|
||||||
def new
|
def new
|
||||||
@bank_account = BankAccount.new(params[:bank_account])
|
@bank_account = BankAccount.new(params[:bank_account])
|
||||||
render :layout => false
|
render layout: false
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
@bank_account = BankAccount.find(params[:id])
|
||||||
|
render action: 'new', layout: false
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@bank_account = BankAccount.new(params[:bank_account])
|
@bank_account = BankAccount.new(params[:bank_account])
|
||||||
if @bank_account.valid? && @bank_account.save
|
if @bank_account.valid? && @bank_account.save
|
||||||
redirect_to update_bank_accounts_admin_finances_url, :status => 303
|
redirect_to update_bank_accounts_admin_finances_url, status: :see_other
|
||||||
else
|
else
|
||||||
render :action => 'new', :layout => false
|
render action: 'new', layout: false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def edit
|
|
||||||
@bank_account = BankAccount.find(params[:id])
|
|
||||||
render :action => 'new', :layout => false
|
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
def update
|
||||||
@bank_account = BankAccount.find(params[:id])
|
@bank_account = BankAccount.find(params[:id])
|
||||||
|
|
||||||
if @bank_account.update(params[:bank_account])
|
if @bank_account.update(params[:bank_account])
|
||||||
redirect_to update_bank_accounts_admin_finances_url, :status => 303
|
redirect_to update_bank_accounts_admin_finances_url, status: :see_other
|
||||||
else
|
else
|
||||||
render :action => 'new', :layout => false
|
render action: 'new', layout: false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
@bank_account = BankAccount.find(params[:id])
|
@bank_account = BankAccount.find(params[:id])
|
||||||
@bank_account.destroy
|
@bank_account.destroy
|
||||||
redirect_to update_bank_accounts_admin_finances_url, :status => 303
|
redirect_to update_bank_accounts_admin_finances_url, status: :see_other
|
||||||
rescue => error
|
rescue StandardError => e
|
||||||
flash.now[:alert] = error.message
|
flash.now[:alert] = e.message
|
||||||
render template: 'shared/alert'
|
render template: 'shared/alert'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,6 +6,11 @@ class Admin::BankGatewaysController < Admin::BaseController
|
||||||
render layout: false
|
render layout: false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
@bank_gateway = BankGateway.find(params[:id])
|
||||||
|
render action: 'new', layout: false
|
||||||
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@bank_gateway = BankGateway.new(params[:bank_gateway])
|
@bank_gateway = BankGateway.new(params[:bank_gateway])
|
||||||
if @bank_gateway.valid? && @bank_gateway.save
|
if @bank_gateway.valid? && @bank_gateway.save
|
||||||
|
@ -15,11 +20,6 @@ class Admin::BankGatewaysController < Admin::BaseController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def edit
|
|
||||||
@bank_gateway = BankGateway.find(params[:id])
|
|
||||||
render action: 'new', layout: false
|
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
def update
|
||||||
@bank_gateway = BankGateway.find(params[:id])
|
@bank_gateway = BankGateway.find(params[:id])
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
class Admin::ConfigsController < Admin::BaseController
|
class Admin::ConfigsController < Admin::BaseController
|
||||||
before_action :get_tabs, only: [:show, :list]
|
before_action :get_tabs, only: %i[show list]
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@current_tab = @tabs.include?(params[:tab]) ? params[:tab] : @tabs.first
|
@current_tab = @tabs.include?(params[:tab]) ? params[:tab] : @tabs.first
|
||||||
|
@ -16,7 +16,7 @@ class Admin::ConfigsController < Admin::BaseController
|
||||||
def update
|
def update
|
||||||
parse_recurring_selects! params[:config][:order_schedule]
|
parse_recurring_selects! params[:config][:order_schedule]
|
||||||
ActiveRecord::Base.transaction do
|
ActiveRecord::Base.transaction do
|
||||||
# TODO support nested configuration keys
|
# TODO: support nested configuration keys
|
||||||
params[:config].each do |key, val|
|
params[:config].each do |key, val|
|
||||||
FoodsoftConfig[key] = convert_config_value val
|
FoodsoftConfig[key] = convert_config_value val
|
||||||
end
|
end
|
||||||
|
@ -29,7 +29,7 @@ class Admin::ConfigsController < Admin::BaseController
|
||||||
|
|
||||||
# Set configuration tab names as `@tabs`
|
# Set configuration tab names as `@tabs`
|
||||||
def get_tabs
|
def get_tabs
|
||||||
@tabs = %w(foodcoop payment tasks messages layout language security others)
|
@tabs = %w[foodcoop payment tasks messages layout language security others]
|
||||||
# allow engines to modify this list
|
# allow engines to modify this list
|
||||||
engines = Rails::Engine.subclasses.map(&:instance).select { |e| e.respond_to?(:configuration) }
|
engines = Rails::Engine.subclasses.map(&:instance).select { |e| e.respond_to?(:configuration) }
|
||||||
engines.each { |e| e.configuration(@tabs, self) }
|
engines.each { |e| e.configuration(@tabs, self) }
|
||||||
|
@ -38,16 +38,16 @@ class Admin::ConfigsController < Admin::BaseController
|
||||||
|
|
||||||
# turn recurring rules into something palatable
|
# turn recurring rules into something palatable
|
||||||
def parse_recurring_selects!(config)
|
def parse_recurring_selects!(config)
|
||||||
if config
|
return unless config
|
||||||
for k in [:pickup, :boxfill, :ends] do
|
|
||||||
if config[k]
|
for k in %i[pickup boxfill ends] do
|
||||||
# allow clearing it using dummy value '{}' ('' would break recurring_select)
|
if config[k]
|
||||||
if config[k][:recurr].present? && config[k][:recurr] != '{}'
|
# allow clearing it using dummy value '{}' ('' would break recurring_select)
|
||||||
config[k][:recurr] = ActiveSupport::JSON.decode(config[k][:recurr])
|
if config[k][:recurr].present? && config[k][:recurr] != '{}'
|
||||||
config[k][:recurr] = FoodsoftDateUtil.rule_from(config[k][:recurr]).to_ical if config[k][:recurr]
|
config[k][:recurr] = ActiveSupport::JSON.decode(config[k][:recurr])
|
||||||
else
|
config[k][:recurr] = FoodsoftDateUtil.rule_from(config[k][:recurr]).to_ical if config[k][:recurr]
|
||||||
config[k] = nil
|
else
|
||||||
end
|
config[k] = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,21 +10,21 @@ class Admin::FinancesController < Admin::BaseController
|
||||||
|
|
||||||
def update_bank_accounts
|
def update_bank_accounts
|
||||||
@bank_accounts = BankAccount.order('name')
|
@bank_accounts = BankAccount.order('name')
|
||||||
render :layout => false
|
render layout: false
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_bank_gateways
|
def update_bank_gateways
|
||||||
@bank_gateways = BankGateway.order('name')
|
@bank_gateways = BankGateway.order('name')
|
||||||
render :layout => false
|
render layout: false
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_transaction_types
|
def update_transaction_types
|
||||||
@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
|
||||||
|
|
||||||
def update_supplier_categories
|
def update_supplier_categories
|
||||||
@supplier_categories = SupplierCategory.order('name')
|
@supplier_categories = SupplierCategory.order('name')
|
||||||
render :layout => false
|
render layout: false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,25 +6,25 @@ class Admin::FinancialTransactionClassesController < Admin::BaseController
|
||||||
render layout: false
|
render layout: false
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
|
||||||
@financial_transaction_class = FinancialTransactionClass.new(params[:financial_transaction_class])
|
|
||||||
if @financial_transaction_class.save
|
|
||||||
redirect_to update_transaction_types_admin_finances_url, status: 303
|
|
||||||
else
|
|
||||||
render action: 'new', layout: false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def edit
|
def edit
|
||||||
@financial_transaction_class = FinancialTransactionClass.find(params[:id])
|
@financial_transaction_class = FinancialTransactionClass.find(params[:id])
|
||||||
render action: 'new', layout: false
|
render action: 'new', layout: false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@financial_transaction_class = FinancialTransactionClass.new(params[:financial_transaction_class])
|
||||||
|
if @financial_transaction_class.save
|
||||||
|
redirect_to update_transaction_types_admin_finances_url, status: :see_other
|
||||||
|
else
|
||||||
|
render action: 'new', layout: false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
@financial_transaction_class = FinancialTransactionClass.find(params[:id])
|
@financial_transaction_class = FinancialTransactionClass.find(params[:id])
|
||||||
|
|
||||||
if @financial_transaction_class.update(params[:financial_transaction_class])
|
if @financial_transaction_class.update(params[:financial_transaction_class])
|
||||||
redirect_to update_transaction_types_admin_finances_url, status: 303
|
redirect_to update_transaction_types_admin_finances_url, status: :see_other
|
||||||
else
|
else
|
||||||
render action: 'new', layout: false
|
render action: 'new', layout: false
|
||||||
end
|
end
|
||||||
|
@ -33,9 +33,9 @@ class Admin::FinancialTransactionClassesController < Admin::BaseController
|
||||||
def destroy
|
def destroy
|
||||||
@financial_transaction_class = FinancialTransactionClass.find(params[:id])
|
@financial_transaction_class = FinancialTransactionClass.find(params[:id])
|
||||||
@financial_transaction_class.destroy!
|
@financial_transaction_class.destroy!
|
||||||
redirect_to update_transaction_types_admin_finances_url, status: 303
|
redirect_to update_transaction_types_admin_finances_url, status: :see_other
|
||||||
rescue => error
|
rescue StandardError => e
|
||||||
flash.now[:alert] = error.message
|
flash.now[:alert] = e.message
|
||||||
render template: 'shared/alert'
|
render template: 'shared/alert'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,25 +7,25 @@ class Admin::FinancialTransactionTypesController < Admin::BaseController
|
||||||
render layout: false
|
render layout: false
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
|
||||||
@financial_transaction_type = FinancialTransactionType.new(params[:financial_transaction_type])
|
|
||||||
if @financial_transaction_type.save
|
|
||||||
redirect_to update_transaction_types_admin_finances_url, status: 303
|
|
||||||
else
|
|
||||||
render action: 'new', layout: false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def edit
|
def edit
|
||||||
@financial_transaction_type = FinancialTransactionType.find(params[:id])
|
@financial_transaction_type = FinancialTransactionType.find(params[:id])
|
||||||
render action: 'new', layout: false
|
render action: 'new', layout: false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@financial_transaction_type = FinancialTransactionType.new(params[:financial_transaction_type])
|
||||||
|
if @financial_transaction_type.save
|
||||||
|
redirect_to update_transaction_types_admin_finances_url, status: :see_other
|
||||||
|
else
|
||||||
|
render action: 'new', layout: false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
@financial_transaction_type = FinancialTransactionType.find(params[:id])
|
@financial_transaction_type = FinancialTransactionType.find(params[:id])
|
||||||
|
|
||||||
if @financial_transaction_type.update(params[:financial_transaction_type])
|
if @financial_transaction_type.update(params[:financial_transaction_type])
|
||||||
redirect_to update_transaction_types_admin_finances_url, status: 303
|
redirect_to update_transaction_types_admin_finances_url, status: :see_other
|
||||||
else
|
else
|
||||||
render action: 'new', layout: false
|
render action: 'new', layout: false
|
||||||
end
|
end
|
||||||
|
@ -34,9 +34,9 @@ class Admin::FinancialTransactionTypesController < Admin::BaseController
|
||||||
def destroy
|
def destroy
|
||||||
@financial_transaction_type = FinancialTransactionType.find(params[:id])
|
@financial_transaction_type = FinancialTransactionType.find(params[:id])
|
||||||
@financial_transaction_type.destroy!
|
@financial_transaction_type.destroy!
|
||||||
redirect_to update_transaction_types_admin_finances_url, status: 303
|
redirect_to update_transaction_types_admin_finances_url, status: :see_other
|
||||||
rescue => error
|
rescue StandardError => e
|
||||||
flash.now[:alert] = error.message
|
flash.now[:alert] = e.message
|
||||||
render template: 'shared/alert'
|
render template: 'shared/alert'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,28 +3,28 @@ class Admin::MailDeliveryStatusController < Admin::BaseController
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@maildeliverystatus = MailDeliveryStatus.order(created_at: :desc)
|
@maildeliverystatus = MailDeliveryStatus.order(created_at: :desc)
|
||||||
@maildeliverystatus = @maildeliverystatus.where(email: params[:email]) unless params[:email].blank?
|
@maildeliverystatus = @maildeliverystatus.where(email: params[:email]) if params[:email].present?
|
||||||
@maildeliverystatus = @maildeliverystatus.page(params[:page]).per(@per_page)
|
@maildeliverystatus = @maildeliverystatus.page(params[:page]).per(@per_page)
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@maildeliverystatus = MailDeliveryStatus.find(params[:id])
|
@maildeliverystatus = MailDeliveryStatus.find(params[:id])
|
||||||
filename = "maildeliverystatus_#{params[:id]}.#{MIME::Types[@maildeliverystatus.attachment_mime].first.preferred_extension}"
|
filename = "maildeliverystatus_#{params[:id]}.#{MIME::Types[@maildeliverystatus.attachment_mime].first.preferred_extension}"
|
||||||
send_data(@maildeliverystatus.attachment_data, :filename => filename, :type => @maildeliverystatus.attachment_mime)
|
send_data(@maildeliverystatus.attachment_data, filename: filename, type: @maildeliverystatus.attachment_mime)
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy_all
|
def destroy_all
|
||||||
@maildeliverystatus = MailDeliveryStatus.delete_all
|
@maildeliverystatus = MailDeliveryStatus.delete_all
|
||||||
redirect_to admin_mail_delivery_status_index_path, notice: t('.notice')
|
redirect_to admin_mail_delivery_status_index_path, notice: t('.notice')
|
||||||
rescue => error
|
rescue StandardError => e
|
||||||
redirect_to admin_mail_delivery_status_index_path, alert: I18n.t('errors.general_msg', msg: error.message)
|
redirect_to admin_mail_delivery_status_index_path, alert: I18n.t('errors.general_msg', msg: e.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
@maildeliverystatus = MailDeliveryStatus.find(params[:id])
|
@maildeliverystatus = MailDeliveryStatus.find(params[:id])
|
||||||
@maildeliverystatus.destroy
|
@maildeliverystatus.destroy
|
||||||
redirect_to admin_mail_delivery_status_index_path, notice: t('.notice')
|
redirect_to admin_mail_delivery_status_index_path, notice: t('.notice')
|
||||||
rescue => error
|
rescue StandardError => e
|
||||||
redirect_to admin_mail_delivery_status_index_path, alert: I18n.t('errors.general_msg', msg: error.message)
|
redirect_to admin_mail_delivery_status_index_path, alert: I18n.t('errors.general_msg', msg: e.message)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,16 +2,15 @@ class Admin::OrdergroupsController < Admin::BaseController
|
||||||
inherit_resources
|
inherit_resources
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@ordergroups = Ordergroup.undeleted.sort_by_param(params["sort"])
|
@ordergroups = Ordergroup.undeleted.sort_by_param(params['sort'])
|
||||||
|
|
||||||
if request.format.csv?
|
if request.format.csv?
|
||||||
send_data OrdergroupsCsv.new(@ordergroups).to_csv, filename: 'ordergroups.csv', type: 'text/csv'
|
send_data OrdergroupsCsv.new(@ordergroups).to_csv, filename: 'ordergroups.csv',
|
||||||
|
type: 'text/csv'
|
||||||
end
|
end
|
||||||
|
|
||||||
# if somebody uses the search field:
|
# if somebody uses the search field:
|
||||||
unless params[:query].blank?
|
@ordergroups = @ordergroups.where('name LIKE ?', "%#{params[:query]}%") if params[:query].present?
|
||||||
@ordergroups = @ordergroups.where('name LIKE ?', "%#{params[:query]}%")
|
|
||||||
end
|
|
||||||
|
|
||||||
@ordergroups = @ordergroups.page(params[:page]).per(@per_page)
|
@ordergroups = @ordergroups.page(params[:page]).per(@per_page)
|
||||||
end
|
end
|
||||||
|
@ -19,8 +18,8 @@ class Admin::OrdergroupsController < Admin::BaseController
|
||||||
def destroy
|
def destroy
|
||||||
@ordergroup = Ordergroup.find(params[:id])
|
@ordergroup = Ordergroup.find(params[:id])
|
||||||
@ordergroup.mark_as_deleted
|
@ordergroup.mark_as_deleted
|
||||||
redirect_to admin_ordergroups_url, notice: t('admin.ordergroups.destroy.notice')
|
redirect_to admin_ordergroups_url, notice: t('.notice')
|
||||||
rescue => error
|
rescue StandardError => e
|
||||||
redirect_to admin_ordergroups_url, alert: t('admin.ordergroups.destroy.error')
|
redirect_to admin_ordergroups_url, alert: t('.error')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,6 +6,11 @@ class Admin::SupplierCategoriesController < Admin::BaseController
|
||||||
render layout: false
|
render layout: false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
@supplier_category = SupplierCategory.find(params[:id])
|
||||||
|
render action: 'new', layout: false
|
||||||
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@supplier_category = SupplierCategory.new(params[:supplier_category])
|
@supplier_category = SupplierCategory.new(params[:supplier_category])
|
||||||
if @supplier_category.valid? && @supplier_category.save
|
if @supplier_category.valid? && @supplier_category.save
|
||||||
|
@ -15,11 +20,6 @@ class Admin::SupplierCategoriesController < Admin::BaseController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def edit
|
|
||||||
@supplier_category = SupplierCategory.find(params[:id])
|
|
||||||
render action: 'new', layout: false
|
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
def update
|
||||||
@supplier_category = SupplierCategory.find(params[:id])
|
@supplier_category = SupplierCategory.find(params[:id])
|
||||||
|
|
||||||
|
|
|
@ -3,16 +3,14 @@ class Admin::UsersController < Admin::BaseController
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@users = params[:show_deleted] ? User.deleted : User.undeleted
|
@users = params[:show_deleted] ? User.deleted : User.undeleted
|
||||||
@users = @users.sort_by_param(params["sort"])
|
@users = @users.sort_by_param(params['sort'])
|
||||||
|
|
||||||
@users = @users.includes(:mail_delivery_status)
|
@users = @users.includes(:mail_delivery_status)
|
||||||
|
|
||||||
if request.format.csv?
|
send_data UsersCsv.new(@users).to_csv, filename: 'users.csv', type: 'text/csv' if request.format.csv?
|
||||||
send_data UsersCsv.new(@users).to_csv, filename: 'users.csv', type: 'text/csv'
|
|
||||||
end
|
|
||||||
|
|
||||||
# if somebody uses the search field:
|
# if somebody uses the search field:
|
||||||
@users = @users.natural_search(params[:user_name]) unless params[:user_name].blank?
|
@users = @users.natural_search(params[:user_name]) if params[:user_name].present?
|
||||||
|
|
||||||
@users = @users.page(params[:page]).per(@per_page)
|
@users = @users.page(params[:page]).per(@per_page)
|
||||||
end
|
end
|
||||||
|
@ -20,17 +18,17 @@ class Admin::UsersController < Admin::BaseController
|
||||||
def destroy
|
def destroy
|
||||||
@user = User.find(params[:id])
|
@user = User.find(params[:id])
|
||||||
@user.mark_as_deleted
|
@user.mark_as_deleted
|
||||||
redirect_to admin_users_url, notice: t('admin.users.destroy.notice')
|
redirect_to admin_users_url, notice: t('.notice')
|
||||||
rescue => error
|
rescue StandardError => e
|
||||||
redirect_to admin_users_url, alert: t('admin.users.destroy.error', error: error.message)
|
redirect_to admin_users_url, alert: t('.error', error: e.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
def restore
|
def restore
|
||||||
@user = User.find(params[:id])
|
@user = User.find(params[:id])
|
||||||
@user.restore
|
@user.restore
|
||||||
redirect_to admin_users_url, notice: t('admin.users.restore.notice')
|
redirect_to admin_users_url, notice: t('.notice')
|
||||||
rescue => error
|
rescue StandardError => e
|
||||||
redirect_to admin_users_url, alert: t('admin.users.restore.error', error: error.message)
|
redirect_to admin_users_url, alert: t('.error', error: e.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
def sudo
|
def sudo
|
||||||
|
|
|
@ -4,7 +4,7 @@ class Admin::WorkgroupsController < Admin::BaseController
|
||||||
def index
|
def index
|
||||||
@workgroups = Workgroup.order('name ASC')
|
@workgroups = Workgroup.order('name ASC')
|
||||||
# if somebody uses the search field:
|
# if somebody uses the search field:
|
||||||
@workgroups = @workgroups.where('name LIKE ?', "%#{params[:query]}%") unless params[:query].blank?
|
@workgroups = @workgroups.where('name LIKE ?', "%#{params[:query]}%") if params[:query].present?
|
||||||
|
|
||||||
@workgroups = @workgroups.page(params[:page]).per(@per_page)
|
@workgroups = @workgroups.page(params[:page]).per(@per_page)
|
||||||
end
|
end
|
||||||
|
@ -12,8 +12,8 @@ class Admin::WorkgroupsController < Admin::BaseController
|
||||||
def destroy
|
def destroy
|
||||||
@workgroup = Workgroup.find(params[:id])
|
@workgroup = Workgroup.find(params[:id])
|
||||||
@workgroup.destroy
|
@workgroup.destroy
|
||||||
redirect_to admin_workgroups_url, notice: t('admin.workgroups.destroy.notice')
|
redirect_to admin_workgroups_url, notice: t('.notice')
|
||||||
rescue => error
|
rescue StandardError => e
|
||||||
redirect_to admin_workgroups_url, alert: t('admin.workgroups.destroy.error', error: error.message)
|
redirect_to admin_workgroups_url, alert: t('.error', error: e.message)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -20,29 +20,30 @@ class Api::V1::BaseController < ApplicationController
|
||||||
|
|
||||||
def require_ordergroup
|
def require_ordergroup
|
||||||
authenticate
|
authenticate
|
||||||
unless current_ordergroup.present?
|
return if current_ordergroup.present?
|
||||||
raise Api::Errors::PermissionRequired.new('Forbidden, must be in an ordergroup')
|
|
||||||
end
|
raise Api::Errors::PermissionRequired, 'Forbidden, must be in an ordergroup'
|
||||||
end
|
end
|
||||||
|
|
||||||
def require_minimum_balance
|
def require_minimum_balance
|
||||||
minimum_balance = FoodsoftConfig[:minimum_balance] or return
|
minimum_balance = FoodsoftConfig[:minimum_balance] or return
|
||||||
if current_ordergroup.account_balance < minimum_balance
|
return unless current_ordergroup.account_balance < minimum_balance
|
||||||
raise Api::Errors::PermissionRequired.new(t('application.controller.error_minimum_balance', min: minimum_balance))
|
|
||||||
end
|
raise Api::Errors::PermissionRequired, t('application.controller.error_minimum_balance', min: minimum_balance)
|
||||||
end
|
end
|
||||||
|
|
||||||
def require_enough_apples
|
def require_enough_apples
|
||||||
if current_ordergroup.not_enough_apples?
|
return unless current_ordergroup.not_enough_apples?
|
||||||
s = t('group_orders.messages.not_enough_apples', apples: current_ordergroup.apples, stop_ordering_under: FoodsoftConfig[:stop_ordering_under])
|
|
||||||
raise Api::Errors::PermissionRequired.new(s)
|
s = t('group_orders.messages.not_enough_apples', apples: current_ordergroup.apples,
|
||||||
end
|
stop_ordering_under: FoodsoftConfig[:stop_ordering_under])
|
||||||
|
raise Api::Errors::PermissionRequired, s
|
||||||
end
|
end
|
||||||
|
|
||||||
def require_config_enabled(config)
|
def require_config_enabled(config)
|
||||||
unless FoodsoftConfig[config]
|
return if FoodsoftConfig[config]
|
||||||
raise Api::Errors::PermissionRequired.new(t('application.controller.error_not_enabled', config: config))
|
|
||||||
end
|
raise Api::Errors::PermissionRequired, t('application.controller.error_not_enabled', config: config)
|
||||||
end
|
end
|
||||||
|
|
||||||
def skip_session
|
def skip_session
|
||||||
|
@ -52,12 +53,12 @@ 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: :not_found, 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: :unprocessable_entity, json: { error: 'not_acceptable', error_description: msg }
|
||||||
end
|
end
|
||||||
|
|
||||||
def doorkeeper_unauthorized_render_options(error:)
|
def doorkeeper_unauthorized_render_options(error:)
|
||||||
|
@ -70,11 +71,11 @@ class Api::V1::BaseController < ApplicationController
|
||||||
|
|
||||||
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: :forbidden, json: { error: 'forbidden', error_description: msg }
|
||||||
end
|
end
|
||||||
|
|
||||||
# @todo something with ApplicationHelper#show_user
|
# @todo something with ApplicationHelper#show_user
|
||||||
def show_user(user = current_user, **options)
|
def show_user(user = current_user, **_options)
|
||||||
user.display
|
user.display
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,7 +16,8 @@ class Api::V1::User::FinancialTransactionsController < Api::V1::BaseController
|
||||||
|
|
||||||
def create
|
def create
|
||||||
transaction_type = FinancialTransactionType.find(create_params[:financial_transaction_type_id])
|
transaction_type = FinancialTransactionType.find(create_params[:financial_transaction_type_id])
|
||||||
ft = current_ordergroup.add_financial_transaction!(create_params[:amount], create_params[:note], current_user, transaction_type)
|
ft = current_ordergroup.add_financial_transaction!(create_params[:amount], create_params[:note], current_user,
|
||||||
|
transaction_type)
|
||||||
render json: ft
|
render json: ft
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,8 @@ class Api::V1::User::GroupOrderArticlesController < Api::V1::BaseController
|
||||||
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: %i[create update] # destroy is ok
|
||||||
before_action :require_enough_apples, only: [:create, :update] # destroy is ok
|
before_action :require_enough_apples, only: %i[create update] # destroy is ok
|
||||||
# @todo allow decreasing amounts when minimum balance isn't met
|
# @todo allow decreasing amounts when minimum balance isn't met
|
||||||
|
|
||||||
def index
|
def index
|
||||||
|
@ -35,7 +35,8 @@ class Api::V1::User::GroupOrderArticlesController < Api::V1::BaseController
|
||||||
goa = nil
|
goa = nil
|
||||||
GroupOrderArticle.transaction do
|
GroupOrderArticle.transaction do
|
||||||
goa = scope_for_update.includes(:group_order_article_quantities).find(params.require(:id))
|
goa = scope_for_update.includes(:group_order_article_quantities).find(params.require(:id))
|
||||||
goa.update_quantities((update_params[:quantity] || goa.quantity).to_i, (update_params[:tolerance] || goa.tolerance).to_i)
|
goa.update_quantities((update_params[:quantity] || goa.quantity).to_i,
|
||||||
|
(update_params[:tolerance] || goa.tolerance).to_i)
|
||||||
goa.order_article.update_results!
|
goa.order_article.update_results!
|
||||||
goa.group_order.update_price!
|
goa.group_order.update_price!
|
||||||
goa.group_order.update!(updated_by: current_user)
|
goa.group_order.update!(updated_by: current_user)
|
||||||
|
|
|
@ -8,13 +8,13 @@ class Api::V1::User::OrdergroupController < Api::V1::BaseController
|
||||||
financial_overview: {
|
financial_overview: {
|
||||||
account_balance: ordergroup.account_balance.to_f,
|
account_balance: ordergroup.account_balance.to_f,
|
||||||
available_funds: ordergroup.get_available_funds.to_f,
|
available_funds: ordergroup.get_available_funds.to_f,
|
||||||
financial_transaction_class_sums: FinancialTransactionClass.sorted.map { |c|
|
financial_transaction_class_sums: FinancialTransactionClass.sorted.map do |c|
|
||||||
{
|
{
|
||||||
id: c.id,
|
id: c.id,
|
||||||
name: c.display,
|
name: c.display,
|
||||||
amount: ordergroup["sum_of_class_#{c.id}"].to_f
|
amount: ordergroup["sum_of_class_#{c.id}"].to_f
|
||||||
}
|
}
|
||||||
}
|
end
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
|
@ -19,10 +19,10 @@ class ApplicationController < ActionController::Base
|
||||||
private
|
private
|
||||||
|
|
||||||
def set_user_last_activity
|
def set_user_last_activity
|
||||||
if current_user && (session[:last_activity] == nil || session[:last_activity] < 1.minutes.ago)
|
return unless current_user && (session[:last_activity].nil? || session[:last_activity] < 1.minute.ago)
|
||||||
current_user.update_attribute(:last_activity, Time.now)
|
|
||||||
session[:last_activity] = Time.now
|
current_user.update_attribute(:last_activity, Time.now)
|
||||||
end
|
session[:last_activity] = Time.now
|
||||||
end
|
end
|
||||||
|
|
||||||
# Many plugins can be turned on and off on the fly with a `use_` configuration option.
|
# Many plugins can be turned on and off on the fly with a `use_` configuration option.
|
||||||
|
@ -64,11 +64,11 @@ class ApplicationController < ActionController::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def items_per_page
|
def items_per_page
|
||||||
if params[:per_page] && params[:per_page].to_i > 0 && params[:per_page].to_i <= 500
|
@per_page = if params[:per_page] && params[:per_page].to_i > 0 && params[:per_page].to_i <= 500
|
||||||
@per_page = params[:per_page].to_i
|
params[:per_page].to_i
|
||||||
else
|
else
|
||||||
@per_page = 20
|
20
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Set timezone according to foodcoop preference.
|
# Set timezone according to foodcoop preference.
|
||||||
|
|
|
@ -4,17 +4,17 @@ class ArticleCategoriesController < ApplicationController
|
||||||
before_action :authenticate_article_meta
|
before_action :authenticate_article_meta
|
||||||
|
|
||||||
def create
|
def create
|
||||||
create!(:notice => I18n.t('article_categories.create.notice')) { article_categories_path }
|
create!(notice: I18n.t('article_categories.create.notice')) { article_categories_path }
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
update!(:notice => I18n.t('article_categories.update.notice')) { article_categories_path }
|
update!(notice: I18n.t('article_categories.update.notice')) { article_categories_path }
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
destroy!
|
destroy!
|
||||||
rescue => error
|
rescue StandardError => e
|
||||||
redirect_to article_categories_path, alert: I18n.t('article_categories.destroy.error', message: error.message)
|
redirect_to article_categories_path, alert: I18n.t('article_categories.destroy.error', message: e.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
|
@ -2,24 +2,24 @@ class ArticlesController < ApplicationController
|
||||||
before_action :authenticate_article_meta, :find_supplier
|
before_action :authenticate_article_meta, :find_supplier
|
||||||
|
|
||||||
def index
|
def index
|
||||||
if params['sort']
|
sort = if params['sort']
|
||||||
sort = case params['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"
|
'article_categories.name, articles.name'
|
||||||
end
|
end
|
||||||
|
|
||||||
@articles = Article.undeleted.where(supplier_id: @supplier, :type => nil).includes(:article_category).order(sort)
|
@articles = Article.undeleted.where(supplier_id: @supplier, type: nil).includes(:article_category).order(sort)
|
||||||
|
|
||||||
if request.format.csv?
|
if request.format.csv?
|
||||||
send_data ArticlesCsv.new(@articles, encoding: 'utf-8').to_csv, filename: 'articles.csv', type: 'text/csv'
|
send_data ArticlesCsv.new(@articles, encoding: 'utf-8').to_csv, filename: 'articles.csv', type: 'text/csv'
|
||||||
|
@ -32,42 +32,42 @@ class ArticlesController < ApplicationController
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html
|
format.html
|
||||||
format.js { render :layout => false }
|
format.js { render layout: false }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def new
|
def new
|
||||||
@article = @supplier.articles.build(:tax => FoodsoftConfig[:tax_default])
|
@article = @supplier.articles.build(tax: FoodsoftConfig[:tax_default])
|
||||||
render :layout => false
|
render layout: false
|
||||||
end
|
end
|
||||||
|
|
||||||
def copy
|
def copy
|
||||||
@article = @supplier.articles.find(params[:article_id]).dup
|
@article = @supplier.articles.find(params[:article_id]).dup
|
||||||
render :layout => false
|
render layout: false
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
@article = Article.find(params[:id])
|
||||||
|
render action: 'new', layout: false
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@article = Article.new(params[:article])
|
@article = Article.new(params[:article])
|
||||||
if @article.valid? && @article.save
|
if @article.valid? && @article.save
|
||||||
render :layout => false
|
render layout: false
|
||||||
else
|
else
|
||||||
render :action => 'new', :layout => false
|
render action: 'new', layout: false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def edit
|
|
||||||
@article = Article.find(params[:id])
|
|
||||||
render :action => 'new', :layout => false
|
|
||||||
end
|
|
||||||
|
|
||||||
# Updates one Article and highlights the line if succeded
|
# Updates one Article and highlights the line if succeded
|
||||||
def update
|
def update
|
||||||
@article = Article.find(params[:id])
|
@article = Article.find(params[:id])
|
||||||
|
|
||||||
if @article.update(params[:article])
|
if @article.update(params[:article])
|
||||||
render :layout => false
|
render layout: false
|
||||||
else
|
else
|
||||||
render :action => 'new', :layout => false
|
render action: 'new', layout: false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ class ArticlesController < ApplicationController
|
||||||
def destroy
|
def destroy
|
||||||
@article = Article.find(params[:id])
|
@article = Article.find(params[:id])
|
||||||
@article.mark_as_deleted unless @order = @article.in_open_order # If article is in an active Order, the Order will be returned
|
@article.mark_as_deleted unless @order = @article.in_open_order # If article is in an active Order, the Order will be returned
|
||||||
render :layout => false
|
render layout: false
|
||||||
end
|
end
|
||||||
|
|
||||||
# Renders a form for editing all articles from a supplier
|
# Renders a form for editing all articles from a supplier
|
||||||
|
@ -87,19 +87,17 @@ class ArticlesController < ApplicationController
|
||||||
def update_all
|
def update_all
|
||||||
invalid_articles = false
|
invalid_articles = false
|
||||||
|
|
||||||
begin
|
Article.transaction do
|
||||||
Article.transaction do
|
if params[:articles].present?
|
||||||
unless params[:articles].blank?
|
# Update other article attributes...
|
||||||
# Update other article attributes...
|
@articles = Article.find(params[:articles].keys)
|
||||||
@articles = Article.find(params[:articles].keys)
|
@articles.each do |article|
|
||||||
@articles.each do |article|
|
unless article.update(params[:articles][article.id.to_s])
|
||||||
unless article.update(params[:articles][article.id.to_s])
|
invalid_articles ||= true # Remember that there are validation errors
|
||||||
invalid_articles = true unless invalid_articles # Remember that there are validation errors
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
raise ActiveRecord::Rollback if invalid_articles # Rollback all changes
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
raise ActiveRecord::Rollback if invalid_articles # Rollback all changes
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -134,16 +132,15 @@ class ArticlesController < ApplicationController
|
||||||
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 StandardError => e
|
||||||
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: e)
|
||||||
end
|
end
|
||||||
|
|
||||||
# lets start with parsing articles from uploaded file, yeah
|
# lets start with parsing articles from uploaded file, yeah
|
||||||
# Renders the upload form
|
# Renders the upload form
|
||||||
def upload
|
def upload; end
|
||||||
end
|
|
||||||
|
|
||||||
# Update articles from a spreadsheet
|
# Update articles from a spreadsheet
|
||||||
def parse_upload
|
def parse_upload
|
||||||
|
@ -151,13 +148,15 @@ class ArticlesController < ApplicationController
|
||||||
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
|
||||||
if @updated_article_pairs.empty? && @outlisted_articles.empty? && @new_articles.empty?
|
if @updated_article_pairs.empty? && @outlisted_articles.empty? && @new_articles.empty?
|
||||||
redirect_to supplier_articles_path(@supplier), :notice => I18n.t('articles.controller.parse_upload.notice')
|
redirect_to supplier_articles_path(@supplier),
|
||||||
|
notice: I18n.t('articles.controller.parse_upload.notice')
|
||||||
end
|
end
|
||||||
@ignored_article_count = 0
|
@ignored_article_count = 0
|
||||||
rescue => error
|
rescue StandardError => e
|
||||||
redirect_to upload_supplier_articles_path(@supplier), :alert => I18n.t('errors.general_msg', :msg => error.message)
|
redirect_to upload_supplier_articles_path(@supplier), alert: I18n.t('errors.general_msg', msg: e.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
# sync all articles with the external database
|
# sync all articles with the external database
|
||||||
|
@ -165,13 +164,14 @@ class ArticlesController < ApplicationController
|
||||||
def sync
|
def sync
|
||||||
# check if there is an shared_supplier
|
# check if there is an shared_supplier
|
||||||
unless @supplier.shared_supplier
|
unless @supplier.shared_supplier
|
||||||
redirect_to supplier_articles_url(@supplier), :alert => I18n.t('articles.controller.sync.shared_alert', :supplier => @supplier.name)
|
redirect_to supplier_articles_url(@supplier),
|
||||||
|
alert: I18n.t('articles.controller.sync.shared_alert', supplier: @supplier.name)
|
||||||
end
|
end
|
||||||
# sync articles against external database
|
# sync articles against external database
|
||||||
@updated_article_pairs, @outlisted_articles, @new_articles = @supplier.sync_all
|
@updated_article_pairs, @outlisted_articles, @new_articles = @supplier.sync_all
|
||||||
if @updated_article_pairs.empty? && @outlisted_articles.empty? && @new_articles.empty?
|
return unless @updated_article_pairs.empty? && @outlisted_articles.empty? && @new_articles.empty?
|
||||||
redirect_to supplier_articles_path(@supplier), :notice => I18n.t('articles.controller.sync.notice')
|
|
||||||
end
|
redirect_to supplier_articles_path(@supplier), notice: I18n.t('articles.controller.sync.notice')
|
||||||
end
|
end
|
||||||
|
|
||||||
# Updates, deletes articles when upload or sync form is submitted
|
# Updates, deletes articles when upload or sync form is submitted
|
||||||
|
@ -186,7 +186,7 @@ class ArticlesController < ApplicationController
|
||||||
# delete articles
|
# delete articles
|
||||||
begin
|
begin
|
||||||
@outlisted_articles.each(&:mark_as_deleted)
|
@outlisted_articles.each(&:mark_as_deleted)
|
||||||
rescue
|
rescue StandardError
|
||||||
# raises an exception when used in current order
|
# raises an exception when used in current order
|
||||||
has_error = true
|
has_error = true
|
||||||
end
|
end
|
||||||
|
@ -198,15 +198,15 @@ class ArticlesController < ApplicationController
|
||||||
raise ActiveRecord::Rollback if has_error
|
raise ActiveRecord::Rollback if has_error
|
||||||
end
|
end
|
||||||
|
|
||||||
if !has_error
|
if has_error
|
||||||
redirect_to supplier_articles_path(@supplier), notice: I18n.t('articles.controller.update_sync.notice')
|
|
||||||
else
|
|
||||||
@updated_article_pairs = @updated_articles.map do |article|
|
@updated_article_pairs = @updated_articles.map do |article|
|
||||||
orig_article = Article.find(article.id)
|
orig_article = Article.find(article.id)
|
||||||
[article, orig_article.unequal_attributes(article)]
|
[article, orig_article.unequal_attributes(article)]
|
||||||
end
|
end
|
||||||
flash.now.alert = I18n.t('articles.controller.error_invalid')
|
flash.now.alert = I18n.t('articles.controller.error_invalid')
|
||||||
render params[:from_action] == 'sync' ? :sync : :parse_upload
|
render params[:from_action] == 'sync' ? :sync : :parse_upload
|
||||||
|
else
|
||||||
|
redirect_to supplier_articles_path(@supplier), notice: I18n.t('articles.controller.update_sync.notice')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -218,18 +218,18 @@ class ArticlesController < ApplicationController
|
||||||
q[:name_cont_all] = params.fetch(:name_cont_all_joined, '').split(' ')
|
q[:name_cont_all] = params.fetch(:name_cont_all_joined, '').split(' ')
|
||||||
search = @supplier.shared_supplier.shared_articles.ransack(q)
|
search = @supplier.shared_supplier.shared_articles.ransack(q)
|
||||||
@articles = search.result.page(params[:page]).per(10)
|
@articles = search.result.page(params[:page]).per(10)
|
||||||
render :layout => false
|
render layout: false
|
||||||
end
|
end
|
||||||
|
|
||||||
# fills a form whith values of the selected shared_article
|
# fills a form whith values of the selected shared_article
|
||||||
# when the direct parameter is set and the article is valid, it is imported directly
|
# when the direct parameter is set and the article is valid, it is imported directly
|
||||||
def import
|
def import
|
||||||
@article = SharedArticle.find(params[:shared_article_id]).build_new_article(@supplier)
|
@article = SharedArticle.find(params[:shared_article_id]).build_new_article(@supplier)
|
||||||
@article.article_category_id = params[:article_category_id] unless params[:article_category_id].blank?
|
@article.article_category_id = params[:article_category_id] if params[:article_category_id].present?
|
||||||
if params[:direct] && !params[:article_category_id].blank? && @article.valid? && @article.save
|
if params[:direct] && params[:article_category_id].present? && @article.valid? && @article.save
|
||||||
render :action => 'create', :layout => false
|
render action: 'create', layout: false
|
||||||
else
|
else
|
||||||
render :action => 'new', :layout => false
|
render action: 'new', layout: false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -9,15 +9,19 @@ module Concerns::Auth
|
||||||
|
|
||||||
def current_user
|
def current_user
|
||||||
# check if there is a valid session and return the logged-in user (its object)
|
# check if there is a valid session and return the logged-in user (its object)
|
||||||
if session[:user_id] && params[:foodcoop]
|
return unless session[:user_id] && params[:foodcoop]
|
||||||
# for shared-host installations. check if the cookie-subdomain fits to request.
|
|
||||||
@current_user ||= User.undeleted.find_by_id(session[:user_id]) if session[:scope] == FoodsoftConfig.scope
|
# for shared-host installations. check if the cookie-subdomain fits to request.
|
||||||
end
|
@current_user ||= User.undeleted.find_by_id(session[:user_id]) if session[:scope] == FoodsoftConfig.scope
|
||||||
end
|
end
|
||||||
|
|
||||||
def deny_access
|
def deny_access
|
||||||
session[:return_to] = request.original_url
|
session[:return_to] = request.original_url
|
||||||
redirect_to root_url, alert: I18n.t('application.controller.error_denied', sign_in: ActionController::Base.helpers.link_to(t('application.controller.error_denied_sign_in'), login_path))
|
redirect_to root_url,
|
||||||
|
alert: I18n.t('application.controller.error_denied',
|
||||||
|
sign_in: ActionController::Base.helpers.link_to(
|
||||||
|
t('application.controller.error_denied_sign_in'), login_path
|
||||||
|
))
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -47,12 +51,7 @@ module Concerns::Auth
|
||||||
|
|
||||||
def authenticate(role = 'any')
|
def authenticate(role = 'any')
|
||||||
# Attempt to retrieve authenticated user from controller instance or session...
|
# Attempt to retrieve authenticated user from controller instance or session...
|
||||||
if !current_user
|
if current_user
|
||||||
# No user at all: redirect to login page.
|
|
||||||
logout
|
|
||||||
session[:return_to] = request.original_url
|
|
||||||
redirect_to_login :alert => I18n.t('application.controller.error_authn')
|
|
||||||
else
|
|
||||||
# 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
|
||||||
|
@ -73,6 +72,11 @@ module Concerns::Auth
|
||||||
else
|
else
|
||||||
deny_access
|
deny_access
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
# No user at all: redirect to login page.
|
||||||
|
logout
|
||||||
|
session[:return_to] = request.original_url
|
||||||
|
redirect_to_login alert: I18n.t('application.controller.error_authn')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -116,13 +120,13 @@ module Concerns::Auth
|
||||||
# if fails the user will redirected to startpage
|
# if fails the user will redirected to startpage
|
||||||
def authenticate_membership_or_admin(group_id = params[:id])
|
def authenticate_membership_or_admin(group_id = params[:id])
|
||||||
@group = Group.find(group_id)
|
@group = Group.find(group_id)
|
||||||
unless @group.member?(@current_user) || @current_user.role_admin?
|
return if @group.member?(@current_user) || @current_user.role_admin?
|
||||||
redirect_to root_path, alert: I18n.t('application.controller.error_members_only')
|
|
||||||
end
|
redirect_to root_path, alert: I18n.t('application.controller.error_members_only')
|
||||||
end
|
end
|
||||||
|
|
||||||
def authenticate_or_token(prefix, role = 'any')
|
def authenticate_or_token(prefix, role = 'any')
|
||||||
if not params[:token].blank?
|
if params[:token].present?
|
||||||
begin
|
begin
|
||||||
TokenVerifier.new(prefix).verify(params[:token])
|
TokenVerifier.new(prefix).verify(params[:token])
|
||||||
rescue ActiveSupport::MessageVerifier::InvalidSignature
|
rescue ActiveSupport::MessageVerifier::InvalidSignature
|
||||||
|
|
|
@ -36,9 +36,9 @@ 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) }
|
return if scopes.any? { |scope| doorkeeper_scope_permitted?(scope) }
|
||||||
raise Api::Errors::PermissionRequired.new('Forbidden, no permission')
|
|
||||||
end
|
raise Api::Errors::PermissionRequired, 'Forbidden, no permission'
|
||||||
end
|
end
|
||||||
|
|
||||||
# Check whether a given OAuth scope is permitted for the current user.
|
# Check whether a given OAuth scope is permitted for the current user.
|
||||||
|
@ -48,9 +48,7 @@ module Concerns::AuthApi
|
||||||
def doorkeeper_scope_permitted?(scope)
|
def doorkeeper_scope_permitted?(scope)
|
||||||
scope_parts = scope.split(':')
|
scope_parts = scope.split(':')
|
||||||
# user sub-scopes like +config:user+ are always permitted
|
# user sub-scopes like +config:user+ are always permitted
|
||||||
if scope_parts.last == 'user'
|
return true if scope_parts.last == 'user'
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
case scope_parts.first
|
case scope_parts.first
|
||||||
when 'user' then return true # access to the current user's own profile
|
when 'user' then return true # access to the current user's own profile
|
||||||
|
@ -64,8 +62,8 @@ module Concerns::AuthApi
|
||||||
end
|
end
|
||||||
|
|
||||||
case scope
|
case scope
|
||||||
when 'orders:read' then return true
|
when 'orders:read' then true
|
||||||
when 'orders:write' then return current_user.role_orders?
|
when 'orders:write' then current_user.role_orders?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -24,12 +24,12 @@ module Concerns::FoodcoopScope
|
||||||
elsif FoodsoftConfig.allowed_foodcoop? foodcoop
|
elsif FoodsoftConfig.allowed_foodcoop? foodcoop
|
||||||
FoodsoftConfig.select_foodcoop foodcoop
|
FoodsoftConfig.select_foodcoop foodcoop
|
||||||
else
|
else
|
||||||
raise ActionController::RoutingError.new 'Foodcoop Not Found'
|
raise ActionController::RoutingError, 'Foodcoop Not Found'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# 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
|
||||||
|
|
|
@ -18,7 +18,7 @@ module Concerns::Locale
|
||||||
end
|
end
|
||||||
|
|
||||||
def browser_language
|
def browser_language
|
||||||
request.env['HTTP_ACCEPT_LANGUAGE'] ? request.env['HTTP_ACCEPT_LANGUAGE'].scan(/^[a-z]{2}/).first : nil
|
request.env['HTTP_ACCEPT_LANGUAGE']&.scan(/^[a-z]{2}/)&.first
|
||||||
end
|
end
|
||||||
|
|
||||||
def default_language
|
def default_language
|
||||||
|
@ -30,7 +30,7 @@ module Concerns::Locale
|
||||||
def select_language_according_to_priority
|
def select_language_according_to_priority
|
||||||
language = explicitly_requested_language || session_language || user_settings_language
|
language = explicitly_requested_language || session_language || user_settings_language
|
||||||
language ||= browser_language unless FoodsoftConfig[:ignore_browser_locale]
|
language ||= browser_language unless FoodsoftConfig[:ignore_browser_locale]
|
||||||
language.presence&.to_sym unless language.blank?
|
language.presence&.to_sym if language.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
def available_locales
|
def available_locales
|
||||||
|
@ -38,11 +38,11 @@ module Concerns::Locale
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_locale
|
def set_locale
|
||||||
if available_locales.include?(select_language_according_to_priority)
|
::I18n.locale = if available_locales.include?(select_language_according_to_priority)
|
||||||
::I18n.locale = select_language_according_to_priority
|
select_language_according_to_priority
|
||||||
else
|
else
|
||||||
::I18n.locale = default_language
|
default_language
|
||||||
end
|
end
|
||||||
|
|
||||||
locale = session[:locale] = ::I18n.locale
|
locale = session[:locale] = ::I18n.locale
|
||||||
logger.info("Set locale to #{locale}")
|
logger.info("Set locale to #{locale}")
|
||||||
|
|
|
@ -3,7 +3,7 @@ module Concerns::SendOrderPdf
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def send_order_pdf order, document
|
def send_order_pdf(order, document)
|
||||||
klass = case document
|
klass = case document
|
||||||
when 'groups' then OrderByGroups
|
when 'groups' then OrderByGroups
|
||||||
when 'articles' then OrderByArticles
|
when 'articles' then OrderByArticles
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
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
|
||||||
@deliveries = @supplier.deliveries.order('date DESC')
|
@deliveries = @supplier.deliveries.order('date DESC')
|
||||||
|
@ -15,6 +15,10 @@ class DeliveriesController < ApplicationController
|
||||||
@delivery.date = Date.today # TODO: move to model/database
|
@delivery.date = Date.today # TODO: move to model/database
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
@delivery = Delivery.find(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@delivery = Delivery.new(params[:delivery])
|
@delivery = Delivery.new(params[:delivery])
|
||||||
|
|
||||||
|
@ -22,14 +26,10 @@ class DeliveriesController < ApplicationController
|
||||||
flash[:notice] = I18n.t('deliveries.create.notice')
|
flash[:notice] = I18n.t('deliveries.create.notice')
|
||||||
redirect_to [@supplier, @delivery]
|
redirect_to [@supplier, @delivery]
|
||||||
else
|
else
|
||||||
render :action => "new"
|
render action: 'new'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def edit
|
|
||||||
@delivery = Delivery.find(params[:id])
|
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
def update
|
||||||
@delivery = Delivery.find(params[:id])
|
@delivery = Delivery.find(params[:id])
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ class DeliveriesController < ApplicationController
|
||||||
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -52,18 +52,18 @@ class DeliveriesController < ApplicationController
|
||||||
def add_stock_change
|
def add_stock_change
|
||||||
@stock_change = StockChange.new
|
@stock_change = StockChange.new
|
||||||
@stock_change.stock_article = StockArticle.find(params[:stock_article_id])
|
@stock_change.stock_article = StockArticle.find(params[:stock_article_id])
|
||||||
render :layout => false
|
render layout: false
|
||||||
end
|
end
|
||||||
|
|
||||||
def form_on_stock_article_create # See publish/subscribe design pattern in /doc.
|
def form_on_stock_article_create # See publish/subscribe design pattern in /doc.
|
||||||
@stock_article = StockArticle.find(params[:id])
|
@stock_article = StockArticle.find(params[:id])
|
||||||
|
|
||||||
render :layout => false
|
render layout: false
|
||||||
end
|
end
|
||||||
|
|
||||||
def form_on_stock_article_update # See publish/subscribe design pattern in /doc.
|
def form_on_stock_article_update # See publish/subscribe design pattern in /doc.
|
||||||
@stock_article = StockArticle.find(params[:id])
|
@stock_article = StockArticle.find(params[:id])
|
||||||
|
|
||||||
render :layout => false
|
render layout: false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
class FeedbackController < ApplicationController
|
class FeedbackController < ApplicationController
|
||||||
def new
|
def new; end
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
def create
|
||||||
if params[:message].present?
|
if params[:message].present?
|
||||||
Mailer.feedback(current_user, params[:message]).deliver_now
|
Mailer.feedback(current_user, params[:message]).deliver_now
|
||||||
redirect_to root_url, notice: t('feedback.create.notice')
|
redirect_to root_url, notice: t('.notice')
|
||||||
else
|
else
|
||||||
render :action => 'new'
|
render action: 'new'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,7 +5,7 @@ class Finance::BalancingController < Finance::BaseController
|
||||||
|
|
||||||
def new
|
def new
|
||||||
@order = Order.find(params[:order_id])
|
@order = Order.find(params[:order_id])
|
||||||
flash.now.alert = t('finance.balancing.new.alert') if @order.closed?
|
flash.now.alert = t('.alert') if @order.closed?
|
||||||
@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,
|
||||||
|
@ -13,13 +13,13 @@ class Finance::BalancingController < Finance::BaseController
|
||||||
|
|
||||||
sort_param = params['sort'] || 'name'
|
sort_param = params['sort'] || 'name'
|
||||||
@articles = case sort_param
|
@articles = case sort_param
|
||||||
when 'name' then
|
when 'name'
|
||||||
@articles.order('articles.name ASC')
|
@articles.order('articles.name ASC')
|
||||||
when 'name_reverse' then
|
when 'name_reverse'
|
||||||
@articles.order('articles.name DESC')
|
@articles.order('articles.name DESC')
|
||||||
when 'order_number' then
|
when 'order_number'
|
||||||
@articles.order('articles.order_number ASC')
|
@articles.order('articles.order_number ASC')
|
||||||
when 'order_number_reverse' then
|
when 'order_number_reverse'
|
||||||
@articles.order('articles.order_number DESC')
|
@articles.order('articles.order_number DESC')
|
||||||
else
|
else
|
||||||
@articles
|
@articles
|
||||||
|
@ -31,13 +31,13 @@ class Finance::BalancingController < Finance::BaseController
|
||||||
def new_on_order_article_create # See publish/subscribe design pattern in /doc.
|
def new_on_order_article_create # See publish/subscribe design pattern in /doc.
|
||||||
@order_article = OrderArticle.find(params[:order_article_id])
|
@order_article = OrderArticle.find(params[:order_article_id])
|
||||||
|
|
||||||
render :layout => false
|
render layout: false
|
||||||
end
|
end
|
||||||
|
|
||||||
def new_on_order_article_update # See publish/subscribe design pattern in /doc.
|
def new_on_order_article_update # See publish/subscribe design pattern in /doc.
|
||||||
@order_article = OrderArticle.find(params[:order_article_id])
|
@order_article = OrderArticle.find(params[:order_article_id])
|
||||||
|
|
||||||
render :layout => false
|
render layout: false
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_summary
|
def update_summary
|
||||||
|
@ -46,29 +46,29 @@ class Finance::BalancingController < Finance::BaseController
|
||||||
|
|
||||||
def edit_note
|
def edit_note
|
||||||
@order = Order.find(params[:id])
|
@order = Order.find(params[:id])
|
||||||
render :layout => false
|
render layout: false
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_note
|
def update_note
|
||||||
@order = Order.find(params[:id])
|
@order = Order.find(params[:id])
|
||||||
if @order.update(params[:order])
|
if @order.update(params[:order])
|
||||||
render :layout => false
|
render layout: false
|
||||||
else
|
else
|
||||||
render :action => :edit_note, :layout => false
|
render action: :edit_note, layout: false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def edit_transport
|
def edit_transport
|
||||||
@order = Order.find(params[:id])
|
@order = Order.find(params[:id])
|
||||||
render :layout => false
|
render layout: false
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_transport
|
def update_transport
|
||||||
@order = Order.find(params[:id])
|
@order = Order.find(params[:id])
|
||||||
@order.update!(params[:order])
|
@order.update!(params[:order])
|
||||||
redirect_to new_finance_order_path(order_id: @order.id)
|
redirect_to new_finance_order_path(order_id: @order.id)
|
||||||
rescue => error
|
rescue StandardError => e
|
||||||
redirect_to new_finance_order_path(order_id: @order.id), alert: t('errors.general_msg', msg: error.message)
|
redirect_to new_finance_order_path(order_id: @order.id), alert: t('errors.general_msg', msg: e.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
# before the order will booked, a view lists all Ordergroups and its order_prices
|
# before the order will booked, a view lists all Ordergroups and its order_prices
|
||||||
|
@ -81,18 +81,18 @@ class Finance::BalancingController < Finance::BaseController
|
||||||
@order = Order.find(params[:id])
|
@order = Order.find(params[:id])
|
||||||
@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('.notice')
|
||||||
rescue => error
|
rescue StandardError => e
|
||||||
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('.alert', message: e.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Close the order directly, without automaticly updating ordergroups account balances
|
# Close the order directly, without automaticly updating ordergroups account balances
|
||||||
def close_direct
|
def close_direct
|
||||||
@order = Order.find(params[:id])
|
@order = Order.find(params[:id])
|
||||||
@order.close_direct!(@current_user)
|
@order.close_direct!(@current_user)
|
||||||
redirect_to finance_order_index_url, notice: t('finance.balancing.close_direct.notice')
|
redirect_to finance_order_index_url, notice: t('.notice')
|
||||||
rescue => error
|
rescue StandardError => e
|
||||||
redirect_to finance_order_index_url, alert: t('finance.balancing.close_direct.alert', message: error.message)
|
redirect_to finance_order_index_url, alert: t('.alert', message: e.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
def close_all_direct_with_invoice
|
def close_all_direct_with_invoice
|
||||||
|
@ -103,8 +103,8 @@ class Finance::BalancingController < Finance::BaseController
|
||||||
count += 1
|
count += 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
redirect_to finance_order_index_url, notice: t('finance.balancing.close_all_direct_with_invoice.notice', count: count)
|
redirect_to finance_order_index_url, notice: t('.notice', count: count)
|
||||||
rescue => error
|
rescue StandardError => e
|
||||||
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: e.message)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,8 +8,8 @@ class Finance::BankAccountsController < Finance::BaseController
|
||||||
@bank_account = BankAccount.find(params[:id])
|
@bank_account = BankAccount.find(params[:id])
|
||||||
count = @bank_account.assign_unlinked_transactions
|
count = @bank_account.assign_unlinked_transactions
|
||||||
redirect_to finance_bank_account_transactions_url(@bank_account), notice: t('.notice', count: count)
|
redirect_to finance_bank_account_transactions_url(@bank_account), notice: t('.notice', count: count)
|
||||||
rescue => error
|
rescue StandardError => e
|
||||||
redirect_to finance_bank_account_transactions_url(@bank_account), alert: t('errors.general_msg', msg: error.message)
|
redirect_to finance_bank_account_transactions_url(@bank_account), alert: t('errors.general_msg', msg: e.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
def import
|
def import
|
||||||
|
@ -33,8 +33,8 @@ class Finance::BankAccountsController < Finance::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
needs_redirect = ok
|
needs_redirect = ok
|
||||||
rescue => error
|
rescue StandardError => e
|
||||||
flash.alert = t('errors.general_msg', msg: error.message)
|
flash.alert = t('errors.general_msg', msg: e.message)
|
||||||
needs_redirect = true
|
needs_redirect = true
|
||||||
ensure
|
ensure
|
||||||
return unless needs_redirect
|
return unless needs_redirect
|
||||||
|
|
|
@ -3,26 +3,30 @@ class Finance::BankTransactionsController < ApplicationController
|
||||||
inherit_resources
|
inherit_resources
|
||||||
|
|
||||||
def index
|
def index
|
||||||
if params["sort"]
|
sort = if params['sort']
|
||||||
sort = case params["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"
|
'date DESC'
|
||||||
end
|
end
|
||||||
|
|
||||||
@bank_account = BankAccount.find(params[:bank_account_id])
|
@bank_account = BankAccount.find(params[:bank_account_id])
|
||||||
@bank_transactions_all = @bank_account.bank_transactions.order(sort).includes(:financial_link)
|
@bank_transactions_all = @bank_account.bank_transactions.order(sort).includes(:financial_link)
|
||||||
@bank_transactions_all = @bank_transactions_all.where('reference LIKE ? OR text LIKE ?', "%#{params[:query]}%", "%#{params[:query]}%") unless params[:query].nil?
|
unless params[:query].nil?
|
||||||
|
@bank_transactions_all = @bank_transactions_all.where('reference LIKE ? OR text LIKE ?', "%#{params[:query]}%",
|
||||||
|
"%#{params[:query]}%")
|
||||||
|
end
|
||||||
@bank_transactions = @bank_transactions_all.page(params[:page]).per(@per_page)
|
@bank_transactions = @bank_transactions_all.page(params[:page]).per(@per_page)
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.js; format.html { render }
|
format.js
|
||||||
|
format.html { render }
|
||||||
format.csv do
|
format.csv do
|
||||||
send_data BankTransactionsCsv.new(@bank_transactions_all).to_csv, filename: 'transactions.csv', type: 'text/csv'
|
send_data BankTransactionsCsv.new(@bank_transactions_all).to_csv, filename: 'transactions.csv', type: 'text/csv'
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
class Finance::FinancialLinksController < Finance::BaseController
|
class Finance::FinancialLinksController < Finance::BaseController
|
||||||
before_action :find_financial_link, except: [:create, :incomplete]
|
before_action :find_financial_link, except: %i[create incomplete]
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@items = @financial_link.bank_transactions.map do |bt|
|
@items = @financial_link.bank_transactions.map do |bt|
|
||||||
|
@ -37,7 +37,7 @@ class Finance::FinancialLinksController < Finance::BaseController
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@financial_link = FinancialLink.first_unused_or_create
|
@financial_link = FinancialLink.first_unused_or_create
|
||||||
if params[:bank_transaction] then
|
if params[:bank_transaction]
|
||||||
bank_transaction = BankTransaction.find(params[:bank_transaction])
|
bank_transaction = BankTransaction.find(params[:bank_transaction])
|
||||||
bank_transaction.update_attribute :financial_link, @financial_link
|
bank_transaction.update_attribute :financial_link, @financial_link
|
||||||
end
|
end
|
||||||
|
@ -72,14 +72,16 @@ class Finance::FinancialLinksController < Finance::BaseController
|
||||||
|
|
||||||
def create_financial_transaction
|
def create_financial_transaction
|
||||||
financial_transaction = FinancialTransaction.new(financial_transaction_params)
|
financial_transaction = FinancialTransaction.new(financial_transaction_params)
|
||||||
financial_transaction.ordergroup.add_financial_transaction! financial_transaction.amount, financial_transaction.note, current_user, financial_transaction.financial_transaction_type, @financial_link
|
financial_transaction.ordergroup.add_financial_transaction! financial_transaction.amount,
|
||||||
|
financial_transaction.note, current_user, financial_transaction.financial_transaction_type, @financial_link
|
||||||
redirect_to finance_link_url(@financial_link), notice: t('.notice')
|
redirect_to finance_link_url(@financial_link), notice: t('.notice')
|
||||||
rescue => error
|
rescue StandardError => e
|
||||||
redirect_to finance_link_url(@financial_link), alert: t('errors.general_msg', msg: error)
|
redirect_to finance_link_url(@financial_link), alert: t('errors.general_msg', msg: e)
|
||||||
end
|
end
|
||||||
|
|
||||||
def index_financial_transaction
|
def index_financial_transaction
|
||||||
@financial_transactions = FinancialTransaction.without_financial_link.includes(:financial_transaction_type, :ordergroup)
|
@financial_transactions = FinancialTransaction.without_financial_link.includes(:financial_transaction_type,
|
||||||
|
:ordergroup)
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_financial_transaction
|
def add_financial_transaction
|
||||||
|
@ -123,7 +125,7 @@ class Finance::FinancialLinksController < Finance::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_best_fitting_ordergroup_id_for_financial_link(financial_link_id)
|
def find_best_fitting_ordergroup_id_for_financial_link(financial_link_id)
|
||||||
FinancialTransaction.joins(<<-SQL).order(created_on: :desc).pluck(:ordergroup_id).first
|
FinancialTransaction.joins(<<-SQL).order(created_on: :desc).pick(:ordergroup_id)
|
||||||
JOIN bank_transactions a ON financial_transactions.financial_link_id = a.financial_link_id
|
JOIN bank_transactions a ON financial_transactions.financial_link_id = a.financial_link_id
|
||||||
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
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
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: %i[new_collection create_collection index_collection]
|
||||||
inherit_resources
|
inherit_resources
|
||||||
# belongs_to :ordergroup
|
# belongs_to :ordergroup
|
||||||
|
|
||||||
def index
|
def index
|
||||||
if params['sort']
|
sort = if params['sort']
|
||||||
sort = case params['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"
|
'created_on DESC'
|
||||||
end
|
end
|
||||||
|
|
||||||
@q = FinancialTransaction.ransack(params[:q])
|
@q = FinancialTransaction.ransack(params[:q])
|
||||||
@financial_transactions_all = @q.result(distinct: true).includes(:user).order(sort)
|
@financial_transactions_all = @q.result(distinct: true).includes(:user).order(sort)
|
||||||
|
@ -26,9 +26,11 @@ class Finance::FinancialTransactionsController < ApplicationController
|
||||||
@financial_transactions = @financial_transactions_all.page(params[:page]).per(@per_page)
|
@financial_transactions = @financial_transactions_all.page(params[:page]).per(@per_page)
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.js; format.html { render }
|
format.js
|
||||||
|
format.html { render }
|
||||||
format.csv do
|
format.csv do
|
||||||
send_data FinancialTransactionsCsv.new(@financial_transactions_all).to_csv, filename: 'transactions.csv', type: 'text/csv'
|
send_data FinancialTransactionsCsv.new(@financial_transactions_all).to_csv, filename: 'transactions.csv',
|
||||||
|
type: 'text/csv'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -38,11 +40,11 @@ class Finance::FinancialTransactionsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def new
|
def new
|
||||||
if @ordergroup
|
@financial_transaction = if @ordergroup
|
||||||
@financial_transaction = @ordergroup.financial_transactions.build
|
@ordergroup.financial_transactions.build
|
||||||
else
|
else
|
||||||
@financial_transaction = FinancialTransaction.new
|
FinancialTransaction.new
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
|
@ -53,16 +55,18 @@ class Finance::FinancialTransactionsController < ApplicationController
|
||||||
else
|
else
|
||||||
@financial_transaction.save!
|
@financial_transaction.save!
|
||||||
end
|
end
|
||||||
redirect_to finance_group_transactions_path(@ordergroup), notice: I18n.t('finance.financial_transactions.controller.create.notice')
|
redirect_to finance_group_transactions_path(@ordergroup),
|
||||||
rescue ActiveRecord::RecordInvalid => error
|
notice: I18n.t('finance.financial_transactions.controller.create.notice')
|
||||||
flash.now[:alert] = error.message
|
rescue ActiveRecord::RecordInvalid => e
|
||||||
render :action => :new
|
flash.now[:alert] = e.message
|
||||||
|
render action: :new
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
transaction = FinancialTransaction.find(params[:id])
|
transaction = FinancialTransaction.find(params[:id])
|
||||||
transaction.revert!(current_user)
|
transaction.revert!(current_user)
|
||||||
redirect_to finance_group_transactions_path(transaction.ordergroup), notice: t('finance.financial_transactions.controller.destroy.notice')
|
redirect_to finance_group_transactions_path(transaction.ordergroup),
|
||||||
|
notice: t('finance.financial_transactions.controller.destroy.notice')
|
||||||
end
|
end
|
||||||
|
|
||||||
def new_collection
|
def new_collection
|
||||||
|
@ -88,17 +92,17 @@ class Finance::FinancialTransactionsController < ApplicationController
|
||||||
|
|
||||||
params[:financial_transactions].each do |trans|
|
params[:financial_transactions].each do |trans|
|
||||||
# ignore empty amount fields ...
|
# ignore empty amount fields ...
|
||||||
unless trans[:amount].blank?
|
next if trans[:amount].blank?
|
||||||
amount = LocalizeInput.parse(trans[:amount]).to_f
|
|
||||||
note = params[:note]
|
amount = LocalizeInput.parse(trans[:amount]).to_f
|
||||||
ordergroup = Ordergroup.find(trans[:ordergroup_id])
|
note = params[:note]
|
||||||
if params[:set_balance]
|
ordergroup = Ordergroup.find(trans[:ordergroup_id])
|
||||||
note += " (#{amount})"
|
if params[:set_balance]
|
||||||
amount -= ordergroup.financial_transaction_class_balance(type.financial_transaction_class)
|
note += " (#{amount})"
|
||||||
end
|
amount -= ordergroup.financial_transaction_class_balance(type.financial_transaction_class)
|
||||||
ordergroup.add_financial_transaction!(amount, note, @current_user, type, financial_link)
|
|
||||||
foodcoop_amount -= amount
|
|
||||||
end
|
end
|
||||||
|
ordergroup.add_financial_transaction!(amount, note, @current_user, type, financial_link)
|
||||||
|
foodcoop_amount -= amount
|
||||||
end
|
end
|
||||||
|
|
||||||
if params[:create_foodcoop_transaction]
|
if params[:create_foodcoop_transaction]
|
||||||
|
@ -107,7 +111,7 @@ class Finance::FinancialTransactionsController < ApplicationController
|
||||||
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
|
||||||
|
@ -117,8 +121,8 @@ class Finance::FinancialTransactionsController < ApplicationController
|
||||||
|
|
||||||
url = financial_link ? finance_link_url(financial_link.id) : finance_ordergroups_url
|
url = financial_link ? finance_link_url(financial_link.id) : finance_ordergroups_url
|
||||||
redirect_to url, notice: I18n.t('finance.financial_transactions.controller.create_collection.notice')
|
redirect_to url, notice: I18n.t('finance.financial_transactions.controller.create_collection.notice')
|
||||||
rescue => error
|
rescue StandardError => e
|
||||||
flash.now[:alert] = error.message
|
flash.now[:alert] = e.message
|
||||||
render action: :new_collection
|
render action: :new_collection
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
class Finance::InvoicesController < ApplicationController
|
class Finance::InvoicesController < ApplicationController
|
||||||
before_action :authenticate_finance_or_invoices
|
before_action :authenticate_finance_or_invoices
|
||||||
|
|
||||||
before_action :find_invoice, only: [:show, :edit, :update, :destroy]
|
before_action :find_invoice, only: %i[show edit update destroy]
|
||||||
before_action :ensure_can_edit, only: [:edit, :update, :destroy]
|
before_action :ensure_can_edit, only: %i[edit update destroy]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@invoices_all = Invoice.includes(:supplier, :deliveries, :orders).order('date DESC')
|
@invoices_all = Invoice.includes(:supplier, :deliveries, :orders).order('date DESC')
|
||||||
@invoices = @invoices_all.page(params[:page]).per(@per_page)
|
@invoices = @invoices_all.page(params[:page]).per(@per_page)
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.js; format.html { render }
|
format.js
|
||||||
|
format.html { render }
|
||||||
format.csv do
|
format.csv do
|
||||||
send_data InvoicesCsv.new(@invoices_all).to_csv, filename: 'invoices.csv', type: 'text/csv'
|
send_data InvoicesCsv.new(@invoices_all).to_csv, filename: 'invoices.csv', type: 'text/csv'
|
||||||
end
|
end
|
||||||
|
@ -20,11 +21,10 @@ class Finance::InvoicesController < ApplicationController
|
||||||
@suppliers = Supplier.includes(:invoices).where('invoices.paid_on IS NULL').references(:invoices)
|
@suppliers = Supplier.includes(:invoices).where('invoices.paid_on IS NULL').references(:invoices)
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show; end
|
||||||
end
|
|
||||||
|
|
||||||
def new
|
def new
|
||||||
@invoice = Invoice.new :supplier_id => params[:supplier_id]
|
@invoice = Invoice.new supplier_id: params[:supplier_id]
|
||||||
@invoice.deliveries << Delivery.find_by_id(params[:delivery_id]) if params[:delivery_id]
|
@invoice.deliveries << Delivery.find_by_id(params[:delivery_id]) if params[:delivery_id]
|
||||||
@invoice.orders << Order.find_by_id(params[:order_id]) if params[:order_id]
|
@invoice.orders << Order.find_by_id(params[:order_id]) if params[:order_id]
|
||||||
fill_deliveries_and_orders_collection @invoice.id, @invoice.supplier_id
|
fill_deliveries_and_orders_collection @invoice.id, @invoice.supplier_id
|
||||||
|
@ -36,12 +36,14 @@ class Finance::InvoicesController < ApplicationController
|
||||||
|
|
||||||
def form_on_supplier_id_change
|
def form_on_supplier_id_change
|
||||||
fill_deliveries_and_orders_collection params[:invoice_id], params[:supplier_id]
|
fill_deliveries_and_orders_collection params[:invoice_id], params[:supplier_id]
|
||||||
render :layout => false
|
render layout: false
|
||||||
end
|
end
|
||||||
|
|
||||||
def fill_deliveries_and_orders_collection(invoice_id, supplier_id)
|
def fill_deliveries_and_orders_collection(invoice_id, supplier_id)
|
||||||
@deliveries_collection = Delivery.where('invoice_id = ? OR (invoice_id IS NULL AND supplier_id = ?)', invoice_id, supplier_id).order(date: :desc).limit(25)
|
@deliveries_collection = Delivery.where('invoice_id = ? OR (invoice_id IS NULL AND supplier_id = ?)', invoice_id,
|
||||||
@orders_collection = Order.where('invoice_id = ? OR (invoice_id IS NULL AND supplier_id = ?)', invoice_id, supplier_id).order(ends: :desc).limit(25)
|
supplier_id).order(date: :desc).limit(25)
|
||||||
|
@orders_collection = Order.where('invoice_id = ? OR (invoice_id IS NULL AND supplier_id = ?)', invoice_id,
|
||||||
|
supplier_id).order(ends: :desc).limit(25)
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
|
@ -58,7 +60,7 @@ class Finance::InvoicesController < ApplicationController
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
fill_deliveries_and_orders_collection @invoice.id, @invoice.supplier_id
|
fill_deliveries_and_orders_collection @invoice.id, @invoice.supplier_id
|
||||||
render :action => "new"
|
render action: 'new'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -81,7 +83,7 @@ class Finance::InvoicesController < ApplicationController
|
||||||
@invoice = Invoice.find(params[:invoice_id])
|
@invoice = Invoice.find(params[:invoice_id])
|
||||||
type = MIME::Types[@invoice.attachment_mime].first
|
type = MIME::Types[@invoice.attachment_mime].first
|
||||||
filename = "invoice_#{@invoice.id}_attachment.#{type.preferred_extension}"
|
filename = "invoice_#{@invoice.id}_attachment.#{type.preferred_extension}"
|
||||||
send_data(@invoice.attachment_data, :filename => filename, :type => type)
|
send_data(@invoice.attachment_data, filename: filename, type: type)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -92,8 +94,8 @@ class Finance::InvoicesController < ApplicationController
|
||||||
|
|
||||||
# Returns true if @current_user can edit the invoice..
|
# Returns true if @current_user can edit the invoice..
|
||||||
def ensure_can_edit
|
def ensure_can_edit
|
||||||
unless @invoice.user_can_edit?(current_user)
|
return if @invoice.user_can_edit?(current_user)
|
||||||
deny_access
|
|
||||||
end
|
deny_access
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
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
|
||||||
sort = m[:col]
|
sort = m[:col]
|
||||||
sort += ' DESC' if m[:reverse]
|
sort += ' DESC' if m[:reverse]
|
||||||
else
|
else
|
||||||
sort = "name"
|
sort = 'name'
|
||||||
end
|
end
|
||||||
|
|
||||||
@ordergroups = Ordergroup.undeleted.order(sort)
|
@ordergroups = Ordergroup.undeleted.order(sort)
|
||||||
|
|
|
@ -1,20 +1,16 @@
|
||||||
class Foodcoop::OrdergroupsController < ApplicationController
|
class Foodcoop::OrdergroupsController < ApplicationController
|
||||||
def index
|
def index
|
||||||
@ordergroups = Ordergroup.undeleted.sort_by_param(params["sort"])
|
@ordergroups = Ordergroup.undeleted.sort_by_param(params['sort'])
|
||||||
|
|
||||||
unless params[:name].blank? # Search by name
|
@ordergroups = @ordergroups.where('name LIKE ?', "%#{params[:name]}%") if params[:name].present? # Search by name
|
||||||
@ordergroups = @ordergroups.where('name LIKE ?', "%#{params[:name]}%")
|
|
||||||
end
|
|
||||||
|
|
||||||
if params[:only_active] # Select only active groups
|
@ordergroups = @ordergroups.active if params[:only_active] # Select only active groups
|
||||||
@ordergroups = @ordergroups.active
|
|
||||||
end
|
|
||||||
|
|
||||||
@ordergroups = @ordergroups.page(params[:page]).per(@per_page)
|
@ordergroups = @ordergroups.page(params[:page]).per(@per_page)
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html # index.html.erb
|
format.html # index.html.erb
|
||||||
format.js { render :layout => false }
|
format.js { render layout: false }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,19 +1,20 @@
|
||||||
class Foodcoop::UsersController < ApplicationController
|
class Foodcoop::UsersController < ApplicationController
|
||||||
def index
|
def index
|
||||||
@users = User.undeleted.sort_by_param(params["sort"])
|
@users = User.undeleted.sort_by_param(params['sort'])
|
||||||
|
|
||||||
# if somebody uses the search field:
|
# if somebody uses the search field:
|
||||||
@users = @users.natural_search(params[:user_name]) unless params[:user_name].blank?
|
@users = @users.natural_search(params[:user_name]) if params[:user_name].present?
|
||||||
|
|
||||||
if params[:ordergroup_name]
|
if params[:ordergroup_name]
|
||||||
@users = @users.joins(:groups).where("groups.type = 'Ordergroup' AND groups.name LIKE ?", "%#{params[:ordergroup_name]}%")
|
@users = @users.joins(:groups).where("groups.type = 'Ordergroup' AND groups.name LIKE ?",
|
||||||
|
"%#{params[:ordergroup_name]}%")
|
||||||
end
|
end
|
||||||
|
|
||||||
@users = @users.page(params[:page]).per(@per_page)
|
@users = @users.page(params[:page]).per(@per_page)
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html # index.html.haml
|
format.html # index.html.haml
|
||||||
format.js { render :layout => false } # index.js.erb
|
format.js { render layout: false } # index.js.erb
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
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
|
||||||
|
@ -13,9 +13,9 @@ class Foodcoop::WorkgroupsController < ApplicationController
|
||||||
def update
|
def update
|
||||||
@workgroup = Workgroup.find(params[:id])
|
@workgroup = Workgroup.find(params[:id])
|
||||||
if @workgroup.update(params[:workgroup])
|
if @workgroup.update(params[:workgroup])
|
||||||
redirect_to foodcoop_workgroups_url, :notice => I18n.t('workgroups.update.notice')
|
redirect_to foodcoop_workgroups_url, notice: I18n.t('workgroups.update.notice')
|
||||||
else
|
else
|
||||||
render :action => 'edit'
|
render action: 'edit'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
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: %i[new create]
|
||||||
|
|
||||||
layout false # We only use this controller to server js snippets, no need for layout rendering
|
layout false # We only use this controller to server js snippets, no need for layout rendering
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
class GroupOrdersController < ApplicationController
|
class GroupOrdersController < ApplicationController
|
||||||
# Security
|
# Security
|
||||||
before_action :ensure_ordergroup_member
|
before_action :ensure_ordergroup_member
|
||||||
before_action :ensure_open_order, :only => [:new, :create, :edit, :update, :order, :stock_order, :saveOrder]
|
before_action :ensure_open_order, only: %i[new create edit update order stock_order saveOrder]
|
||||||
before_action :ensure_my_group_order, only: [:show, :edit, :update]
|
before_action :ensure_my_group_order, only: %i[show edit update]
|
||||||
before_action :enough_apples?, only: [:new, :create]
|
before_action :enough_apples?, only: %i[new create]
|
||||||
|
|
||||||
# Index page.
|
# Index page.
|
||||||
def index
|
def index
|
||||||
|
@ -13,9 +13,17 @@ class GroupOrdersController < ApplicationController
|
||||||
@finished_not_closed_orders_including_group_order = Order.finished_not_closed.ordergroup_group_orders_map(@ordergroup)
|
@finished_not_closed_orders_including_group_order = Order.finished_not_closed.ordergroup_group_orders_map(@ordergroup)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
@order = @group_order.order
|
||||||
|
end
|
||||||
|
|
||||||
def new
|
def new
|
||||||
ordergroup = params[:stock_order] ? nil : @ordergroup
|
ordergroup = params[:stock_order] ? nil : @ordergroup
|
||||||
@group_order = @order.group_orders.build(:ordergroup => ordergroup, :updated_by => current_user)
|
@group_order = @order.group_orders.build(ordergroup: ordergroup, updated_by: current_user)
|
||||||
|
@ordering_data = @group_order.load_data
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
@ordering_data = @group_order.load_data
|
@ordering_data = @group_order.load_data
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -23,34 +31,26 @@ class GroupOrdersController < ApplicationController
|
||||||
@group_order = GroupOrder.new(params[:group_order])
|
@group_order = GroupOrder.new(params[:group_order])
|
||||||
begin
|
begin
|
||||||
@group_order.save_ordering!
|
@group_order.save_ordering!
|
||||||
redirect_to group_order_url(@group_order), :notice => I18n.t('group_orders.create.notice')
|
redirect_to group_order_url(@group_order), notice: I18n.t('group_orders.create.notice')
|
||||||
rescue ActiveRecord::StaleObjectError
|
rescue ActiveRecord::StaleObjectError
|
||||||
redirect_to group_orders_url, :alert => I18n.t('group_orders.create.error_stale')
|
redirect_to group_orders_url, alert: I18n.t('group_orders.create.error_stale')
|
||||||
rescue => exception
|
rescue StandardError => e
|
||||||
logger.error('Failed to update order: ' + exception.message)
|
logger.error('Failed to update order: ' + e.message)
|
||||||
redirect_to group_orders_url, :alert => I18n.t('group_orders.create.error_general')
|
redirect_to group_orders_url, alert: I18n.t('group_orders.create.error_general')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
|
||||||
@order = @group_order.order
|
|
||||||
end
|
|
||||||
|
|
||||||
def edit
|
|
||||||
@ordering_data = @group_order.load_data
|
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
def update
|
||||||
@group_order.attributes = params[:group_order]
|
@group_order.attributes = params[:group_order]
|
||||||
@group_order.updated_by = current_user
|
@group_order.updated_by = current_user
|
||||||
begin
|
begin
|
||||||
@group_order.save_ordering!
|
@group_order.save_ordering!
|
||||||
redirect_to group_order_url(@group_order), :notice => I18n.t('group_orders.update.notice')
|
redirect_to group_order_url(@group_order), notice: I18n.t('group_orders.update.notice')
|
||||||
rescue ActiveRecord::StaleObjectError
|
rescue ActiveRecord::StaleObjectError
|
||||||
redirect_to group_orders_url, :alert => I18n.t('group_orders.update.error_stale')
|
redirect_to group_orders_url, alert: I18n.t('group_orders.update.error_stale')
|
||||||
rescue => exception
|
rescue StandardError => e
|
||||||
logger.error('Failed to update order: ' + exception.message)
|
logger.error('Failed to update order: ' + e.message)
|
||||||
redirect_to group_orders_url, :alert => I18n.t('group_orders.update.error_general')
|
redirect_to group_orders_url, alert: I18n.t('group_orders.update.error_general')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -74,16 +74,16 @@ class GroupOrdersController < ApplicationController
|
||||||
# Used as a :before_action by OrdersController.
|
# Used as a :before_action by OrdersController.
|
||||||
def ensure_ordergroup_member
|
def ensure_ordergroup_member
|
||||||
@ordergroup = @current_user.ordergroup
|
@ordergroup = @current_user.ordergroup
|
||||||
if @ordergroup.nil?
|
return unless @ordergroup.nil?
|
||||||
redirect_to root_url, :alert => I18n.t('group_orders.errors.no_member')
|
|
||||||
end
|
redirect_to root_url, alert: I18n.t('group_orders.errors.no_member')
|
||||||
end
|
end
|
||||||
|
|
||||||
def ensure_open_order
|
def ensure_open_order
|
||||||
@order = Order.includes([:supplier, :order_articles]).find(order_id_param)
|
@order = Order.includes(%i[supplier order_articles]).find(order_id_param)
|
||||||
unless @order.open?
|
unless @order.open?
|
||||||
flash[:notice] = I18n.t('group_orders.errors.closed')
|
flash[:notice] = I18n.t('group_orders.errors.closed')
|
||||||
redirect_to :action => 'index'
|
redirect_to action: 'index'
|
||||||
end
|
end
|
||||||
rescue ActiveRecord::RecordNotFound
|
rescue ActiveRecord::RecordNotFound
|
||||||
redirect_to group_orders_url, alert: I18n.t('group_orders.errors.notfound')
|
redirect_to group_orders_url, alert: I18n.t('group_orders.errors.notfound')
|
||||||
|
@ -91,17 +91,17 @@ class GroupOrdersController < ApplicationController
|
||||||
|
|
||||||
def ensure_my_group_order
|
def ensure_my_group_order
|
||||||
@group_order = GroupOrder.find(params[:id])
|
@group_order = GroupOrder.find(params[:id])
|
||||||
if @group_order.ordergroup != @ordergroup && (@group_order.ordergroup || !current_user.role_orders?)
|
return unless @group_order.ordergroup != @ordergroup && (@group_order.ordergroup || !current_user.role_orders?)
|
||||||
redirect_to group_orders_url, alert: I18n.t('group_orders.errors.notfound')
|
|
||||||
end
|
redirect_to group_orders_url, alert: I18n.t('group_orders.errors.notfound')
|
||||||
end
|
end
|
||||||
|
|
||||||
def enough_apples?
|
def enough_apples?
|
||||||
if @ordergroup.not_enough_apples?
|
return unless @ordergroup.not_enough_apples?
|
||||||
redirect_to group_orders_url,
|
|
||||||
alert: t('not_enough_apples', scope: 'group_orders.messages', apples: @ordergroup.apples,
|
redirect_to group_orders_url,
|
||||||
stop_ordering_under: FoodsoftConfig[:stop_ordering_under])
|
alert: t('not_enough_apples', scope: 'group_orders.messages', apples: @ordergroup.apples,
|
||||||
end
|
stop_ordering_under: FoodsoftConfig[:stop_ordering_under])
|
||||||
end
|
end
|
||||||
|
|
||||||
def order_id_param
|
def order_id_param
|
||||||
|
|
|
@ -9,8 +9,7 @@ class HomeController < ApplicationController
|
||||||
@unassigned_tasks = Task.order(:due_date).next_unassigned_tasks_for(current_user)
|
@unassigned_tasks = Task.order(:due_date).next_unassigned_tasks_for(current_user)
|
||||||
end
|
end
|
||||||
|
|
||||||
def profile
|
def profile; end
|
||||||
end
|
|
||||||
|
|
||||||
def reference_calculator
|
def reference_calculator
|
||||||
if current_user.ordergroup
|
if current_user.ordergroup
|
||||||
|
@ -36,40 +35,43 @@ class HomeController < ApplicationController
|
||||||
@user = @current_user
|
@user = @current_user
|
||||||
@ordergroup = @user.ordergroup
|
@ordergroup = @user.ordergroup
|
||||||
|
|
||||||
unless @ordergroup.nil?
|
if @ordergroup.nil?
|
||||||
|
redirect_to root_path, alert: I18n.t('home.no_ordergroups')
|
||||||
|
else
|
||||||
|
|
||||||
@ordergroup = Ordergroup.include_transaction_class_sum.find(@ordergroup.id)
|
@ordergroup = Ordergroup.include_transaction_class_sum.find(@ordergroup.id)
|
||||||
|
|
||||||
if params['sort']
|
sort = if params['sort']
|
||||||
sort = case params['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"
|
'created_on DESC'
|
||||||
end
|
end
|
||||||
|
|
||||||
@financial_transactions = @ordergroup.financial_transactions.visible.page(params[:page]).per(@per_page).order(sort)
|
@financial_transactions = @ordergroup.financial_transactions.visible.page(params[:page]).per(@per_page).order(sort)
|
||||||
@financial_transactions = @financial_transactions.where('financial_transactions.note LIKE ?', "%#{params[:query]}%") if params[:query].present?
|
if params[:query].present?
|
||||||
|
@financial_transactions = @financial_transactions.where('financial_transactions.note LIKE ?',
|
||||||
|
"%#{params[:query]}%")
|
||||||
|
end
|
||||||
|
|
||||||
else
|
|
||||||
redirect_to root_path, alert: I18n.t('home.no_ordergroups')
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# cancel personal memberships direct from the myProfile-page
|
# cancel personal memberships direct from the myProfile-page
|
||||||
def cancel_membership
|
def cancel_membership
|
||||||
if params[:membership_id]
|
membership = if params[:membership_id]
|
||||||
membership = @current_user.memberships.find(params[:membership_id])
|
@current_user.memberships.find(params[:membership_id])
|
||||||
else
|
else
|
||||||
membership = @current_user.memberships.find_by_group_id!(params[:group_id])
|
@current_user.memberships.find_by_group_id!(params[:group_id])
|
||||||
end
|
end
|
||||||
membership.destroy
|
membership.destroy
|
||||||
redirect_to my_profile_path, notice: I18n.t('home.ordergroup_cancelled', :group => membership.group.name)
|
redirect_to my_profile_path, notice: I18n.t('home.ordergroup_cancelled', group: membership.group.name)
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
@ -82,8 +84,8 @@ class HomeController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def ordergroup_params
|
def ordergroup_params
|
||||||
if params[:user][:ordergroup]
|
return unless params[:user][:ordergroup]
|
||||||
params.require(:user).require(:ordergroup).permit(:contact_address)
|
|
||||||
end
|
params.require(:user).require(:ordergroup).permit(:contact_address)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,7 +3,7 @@ class InvitesController < ApplicationController
|
||||||
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
|
||||||
|
@ -27,6 +27,10 @@ class InvitesController < ApplicationController
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def authenticate_membership_or_admin_for_invites
|
def authenticate_membership_or_admin_for_invites
|
||||||
authenticate_membership_or_admin((params[:invite][:group_id] rescue params[:id]))
|
authenticate_membership_or_admin(begin
|
||||||
|
params[:invite][:group_id]
|
||||||
|
rescue StandardError
|
||||||
|
params[:id]
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
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: %i[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
|
||||||
|
@ -9,20 +9,17 @@ class LoginController < ApplicationController
|
||||||
|
|
||||||
# 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.
|
redirect_to forgot_password_url, alert: I18n.t('errors.general_again') and return if request.get? || params[:user].nil? # Catch for get request and give better error message.
|
||||||
redirect_to forgot_password_url, alert: I18n.t('errors.general_again') and return
|
|
||||||
end
|
|
||||||
|
|
||||||
if (user = User.undeleted.find_by_email(params[:user][:email]))
|
if (user = User.undeleted.find_by_email(params[:user][:email]))
|
||||||
user.request_password_reset!
|
user.request_password_reset!
|
||||||
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.
|
||||||
|
@ -32,7 +29,7 @@ class LoginController < ApplicationController
|
||||||
@user.reset_password_token = nil
|
@user.reset_password_token = nil
|
||||||
@user.reset_password_expires = nil
|
@user.reset_password_expires = nil
|
||||||
@user.save
|
@user.save
|
||||||
redirect_to login_url, :notice => I18n.t('login.controller.update_password.notice')
|
redirect_to login_url, notice: I18n.t('login.controller.update_password.notice')
|
||||||
else
|
else
|
||||||
render :new_password
|
render :new_password
|
||||||
end
|
end
|
||||||
|
@ -50,14 +47,14 @@ class LoginController < ApplicationController
|
||||||
@user = User.new(params[:user])
|
@user = User.new(params[:user])
|
||||||
@user.email = @invite.email
|
@user.email = @invite.email
|
||||||
if @user.save
|
if @user.save
|
||||||
Membership.new(:user => @user, :group => @invite.group).save!
|
Membership.new(user: @user, group: @invite.group).save!
|
||||||
@invite.destroy
|
@invite.destroy
|
||||||
session[:locale] = @user.locale
|
session[:locale] = @user.locale
|
||||||
redirect_to login_url, notice: I18n.t('login.controller.accept_invitation.notice')
|
redirect_to login_url, notice: I18n.t('login.controller.accept_invitation.notice')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@user = User.new(:email => @invite.email)
|
@user = User.new(email: @invite.email)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -65,8 +62,8 @@ class LoginController < ApplicationController
|
||||||
|
|
||||||
def validate_token
|
def validate_token
|
||||||
@user = User.find_by_id_and_reset_password_token(params[:id], params[:token])
|
@user = User.find_by_id_and_reset_password_token(params[:id], params[:token])
|
||||||
if (@user.nil? || @user.reset_password_expires < Time.now)
|
return unless @user.nil? || @user.reset_password_expires < Time.now
|
||||||
redirect_to forgot_password_url, alert: I18n.t('login.controller.error_token_invalid')
|
|
||||||
end
|
redirect_to forgot_password_url, alert: I18n.t('login.controller.error_token_invalid')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
class OrderArticlesController < ApplicationController
|
class OrderArticlesController < ApplicationController
|
||||||
before_action :fetch_order, except: :destroy
|
before_action :fetch_order, except: :destroy
|
||||||
before_action :authenticate_finance_or_invoices, except: [:new, :create]
|
before_action :authenticate_finance_or_invoices, except: %i[new create]
|
||||||
before_action :authenticate_finance_orders_or_pickup, except: [:edit, :update, :destroy]
|
before_action :authenticate_finance_orders_or_pickup, except: %i[edit update destroy]
|
||||||
|
|
||||||
layout false # We only use this controller to serve js snippets, no need for layout rendering
|
layout false # We only use this controller to serve js snippets, no need for layout rendering
|
||||||
|
|
||||||
|
@ -9,28 +9,26 @@ class OrderArticlesController < ApplicationController
|
||||||
@order_article = @order.order_articles.build(params[:order_article])
|
@order_article = @order.order_articles.build(params[:order_article])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
@order_article = OrderArticle.find(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
# The article may be ordered with zero units - in that case do not complain.
|
# The article may be ordered with zero units - in that case do not complain.
|
||||||
# If order_article is ordered and a new order_article is created, an error message will be
|
# If order_article is ordered and a new order_article is created, an error message will be
|
||||||
# given mentioning that the article already exists, which is desired.
|
# given mentioning that the article already exists, which is desired.
|
||||||
@order_article = @order.order_articles.where(:article_id => params[:order_article][:article_id]).first
|
@order_article = @order.order_articles.where(article_id: params[:order_article][:article_id]).first
|
||||||
unless @order_article && @order_article.units_to_order == 0
|
@order_article = @order.order_articles.build(params[:order_article]) unless @order_article && @order_article.units_to_order == 0
|
||||||
@order_article = @order.order_articles.build(params[:order_article])
|
|
||||||
end
|
|
||||||
@order_article.save!
|
@order_article.save!
|
||||||
rescue
|
rescue StandardError
|
||||||
render action: :new
|
render action: :new
|
||||||
end
|
end
|
||||||
|
|
||||||
def edit
|
|
||||||
@order_article = OrderArticle.find(params[:id])
|
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
def update
|
||||||
@order_article = OrderArticle.find(params[:id])
|
@order_article = OrderArticle.find(params[:id])
|
||||||
begin
|
begin
|
||||||
@order_article.update_article_and_price!(params[:order_article], params[:article], params[:article_price])
|
@order_article.update_article_and_price!(params[:order_article], params[:article], params[:article_price])
|
||||||
rescue
|
rescue StandardError
|
||||||
render action: :edit
|
render action: :edit
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
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)
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@order_comment = OrderComment.new(params[:order_comment])
|
@order_comment = OrderComment.new(params[:order_comment])
|
||||||
if @order_comment.save
|
if @order_comment.save
|
||||||
render :layout => false
|
render layout: false
|
||||||
else
|
else
|
||||||
render :action => :new, :layout => false
|
render action: :new, layout: false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,25 +5,26 @@ class OrdersController < ApplicationController
|
||||||
include Concerns::SendOrderPdf
|
include Concerns::SendOrderPdf
|
||||||
|
|
||||||
before_action :authenticate_pickups_or_orders
|
before_action :authenticate_pickups_or_orders
|
||||||
before_action :authenticate_orders, except: [:receive, :receive_on_order_article_create, :receive_on_order_article_update, :show]
|
before_action :authenticate_orders,
|
||||||
before_action :remove_empty_article, only: [:create, :update]
|
except: %i[receive receive_on_order_article_create receive_on_order_article_update show]
|
||||||
|
before_action :remove_empty_article, only: %i[create update]
|
||||||
|
|
||||||
# List orders
|
# List orders
|
||||||
def index
|
def index
|
||||||
@open_orders = Order.open.includes(:supplier)
|
@open_orders = Order.open.includes(:supplier)
|
||||||
@finished_orders = Order.finished_not_closed.includes(:supplier)
|
@finished_orders = Order.finished_not_closed.includes(:supplier)
|
||||||
@per_page = 15
|
@per_page = 15
|
||||||
if params['sort']
|
sort = if params['sort']
|
||||||
sort = case params['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"
|
'ends DESC'
|
||||||
end
|
end
|
||||||
@suppliers = Supplier.having_articles.order('suppliers.name')
|
@suppliers = Supplier.having_articles.order('suppliers.name')
|
||||||
@orders = Order.closed.includes(:supplier).reorder(sort).page(params[:page]).per(@per_page)
|
@orders = Order.closed.includes(:supplier).reorder(sort).page(params[:page]).per(@per_page)
|
||||||
end
|
end
|
||||||
|
@ -43,7 +44,7 @@ class OrdersController < ApplicationController
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html
|
format.html
|
||||||
format.js do
|
format.js do
|
||||||
render :layout => false
|
render layout: false
|
||||||
end
|
end
|
||||||
format.pdf do
|
format.pdf do
|
||||||
send_order_pdf @order, params[:document]
|
send_order_pdf @order, params[:document]
|
||||||
|
@ -66,8 +67,14 @@ class OrdersController < ApplicationController
|
||||||
else
|
else
|
||||||
@order = Order.new(supplier_id: params[:supplier_id]).init_dates
|
@order = Order.new(supplier_id: params[:supplier_id]).init_dates
|
||||||
end
|
end
|
||||||
rescue => error
|
rescue StandardError => e
|
||||||
redirect_to orders_url, alert: t('errors.general_msg', msg: error.message)
|
redirect_to orders_url, alert: t('errors.general_msg', msg: e.message)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Page to edit an exsiting order.
|
||||||
|
# editing finished orders is done in FinanceController
|
||||||
|
def edit
|
||||||
|
@order = Order.includes(:articles).find(params[:id])
|
||||||
end
|
end
|
||||||
|
|
||||||
# Save a new order.
|
# Save a new order.
|
||||||
|
@ -81,31 +88,25 @@ class OrdersController < ApplicationController
|
||||||
redirect_to @order
|
redirect_to @order
|
||||||
else
|
else
|
||||||
logger.debug "[debug] order errors: #{@order.errors.messages}"
|
logger.debug "[debug] order errors: #{@order.errors.messages}"
|
||||||
render :action => 'new'
|
render action: 'new'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Page to edit an exsiting order.
|
|
||||||
# editing finished orders is done in FinanceController
|
|
||||||
def edit
|
|
||||||
@order = Order.includes(:articles).find(params[:id])
|
|
||||||
end
|
|
||||||
|
|
||||||
# Update an existing order.
|
# Update an existing order.
|
||||||
def update
|
def update
|
||||||
@order = Order.find params[:id]
|
@order = Order.find params[:id]
|
||||||
if @order.update(params[:order].merge(updated_by: current_user))
|
if @order.update(params[:order].merge(updated_by: current_user))
|
||||||
flash[:notice] = I18n.t('orders.update.notice')
|
flash[:notice] = I18n.t('orders.update.notice')
|
||||||
redirect_to :action => 'show', :id => @order
|
redirect_to action: 'show', id: @order
|
||||||
else
|
else
|
||||||
render :action => 'edit'
|
render action: 'edit'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Delete an order.
|
# Delete an order.
|
||||||
def destroy
|
def destroy
|
||||||
Order.find(params[:id]).destroy
|
Order.find(params[:id]).destroy
|
||||||
redirect_to :action => 'index'
|
redirect_to action: 'index'
|
||||||
end
|
end
|
||||||
|
|
||||||
# Finish a current order.
|
# Finish a current order.
|
||||||
|
@ -113,8 +114,8 @@ class OrdersController < ApplicationController
|
||||||
order = Order.find(params[:id])
|
order = Order.find(params[:id])
|
||||||
order.finish!(@current_user)
|
order.finish!(@current_user)
|
||||||
redirect_to order, notice: I18n.t('orders.finish.notice')
|
redirect_to order, notice: I18n.t('orders.finish.notice')
|
||||||
rescue => error
|
rescue StandardError => e
|
||||||
redirect_to orders_url, alert: I18n.t('errors.general_msg', :msg => error.message)
|
redirect_to orders_url, alert: I18n.t('errors.general_msg', msg: e.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Send a order to the supplier.
|
# Send a order to the supplier.
|
||||||
|
@ -122,20 +123,18 @@ class OrdersController < ApplicationController
|
||||||
order = Order.find(params[:id])
|
order = Order.find(params[:id])
|
||||||
order.send_to_supplier!(@current_user)
|
order.send_to_supplier!(@current_user)
|
||||||
redirect_to order, notice: I18n.t('orders.send_to_supplier.notice')
|
redirect_to order, notice: I18n.t('orders.send_to_supplier.notice')
|
||||||
rescue => error
|
rescue StandardError => e
|
||||||
redirect_to order, alert: I18n.t('errors.general_msg', :msg => error.message)
|
redirect_to order, alert: I18n.t('errors.general_msg', msg: e.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
def receive
|
def receive
|
||||||
@order = Order.find(params[:id])
|
@order = Order.find(params[:id])
|
||||||
unless request.post?
|
if request.post?
|
||||||
@order_articles = @order.order_articles.ordered_or_member.includes(:article).order('articles.order_number, articles.name')
|
|
||||||
else
|
|
||||||
Order.transaction do
|
Order.transaction do
|
||||||
s = update_order_amounts
|
s = update_order_amounts
|
||||||
@order.update_attribute(:state, 'received') if @order.state != 'received'
|
@order.update_attribute(:state, 'received') if @order.state != 'received'
|
||||||
|
|
||||||
flash[:notice] = (s ? I18n.t('orders.receive.notice', :msg => s) : I18n.t('orders.receive.notice_none'))
|
flash[:notice] = (s ? I18n.t('orders.receive.notice', msg: s) : I18n.t('orders.receive.notice_none'))
|
||||||
end
|
end
|
||||||
NotifyReceivedOrderJob.perform_later(@order)
|
NotifyReceivedOrderJob.perform_later(@order)
|
||||||
if current_user.role_orders? || current_user.role_finance?
|
if current_user.role_orders? || current_user.role_finance?
|
||||||
|
@ -145,23 +144,25 @@ class OrdersController < ApplicationController
|
||||||
else
|
else
|
||||||
redirect_to receive_order_path(@order)
|
redirect_to receive_order_path(@order)
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
@order_articles = @order.order_articles.ordered_or_member.includes(:article).order('articles.order_number, articles.name')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def receive_on_order_article_create # See publish/subscribe design pattern in /doc.
|
def receive_on_order_article_create # See publish/subscribe design pattern in /doc.
|
||||||
@order_article = OrderArticle.find(params[:order_article_id])
|
@order_article = OrderArticle.find(params[:order_article_id])
|
||||||
render :layout => false
|
render layout: false
|
||||||
end
|
end
|
||||||
|
|
||||||
def receive_on_order_article_update # See publish/subscribe design pattern in /doc.
|
def receive_on_order_article_update # See publish/subscribe design pattern in /doc.
|
||||||
@order_article = OrderArticle.find(params[:order_article_id])
|
@order_article = OrderArticle.find(params[:order_article_id])
|
||||||
render :layout => false
|
render layout: false
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def update_order_amounts
|
def update_order_amounts
|
||||||
return if not params[:order_articles]
|
return unless params[:order_articles]
|
||||||
|
|
||||||
# where to leave remainder during redistribution
|
# where to leave remainder during redistribution
|
||||||
rest_to = []
|
rest_to = []
|
||||||
|
@ -176,35 +177,42 @@ class OrdersController < ApplicationController
|
||||||
# "MySQL lock timeout exceeded" errors. It's ok to do
|
# "MySQL lock timeout exceeded" errors. It's ok to do
|
||||||
# this article-by-article anway.
|
# this article-by-article anway.
|
||||||
params[:order_articles].each do |oa_id, oa_params|
|
params[:order_articles].each do |oa_id, oa_params|
|
||||||
unless oa_params.blank?
|
next if oa_params.blank?
|
||||||
oa = OrderArticle.find(oa_id)
|
|
||||||
# update attributes; don't use update_attribute because it calls save
|
oa = OrderArticle.find(oa_id)
|
||||||
# which makes received_changed? not work anymore
|
# update attributes; don't use update_attribute because it calls save
|
||||||
oa.attributes = oa_params
|
# which makes received_changed? not work anymore
|
||||||
if oa.units_received_changed?
|
oa.attributes = oa_params
|
||||||
counts[0] += 1
|
if oa.units_received_changed?
|
||||||
unless oa.units_received.blank?
|
counts[0] += 1
|
||||||
cunits[0] += oa.units_received * oa.article.unit_quantity
|
if oa.units_received.present?
|
||||||
oacounts = oa.redistribute oa.units_received * oa.price.unit_quantity, rest_to
|
cunits[0] += oa.units_received * oa.article.unit_quantity
|
||||||
oacounts.each_with_index { |c, i| cunits[i + 1] += c; counts[i + 1] += 1 if c > 0 }
|
oacounts = oa.redistribute oa.units_received * oa.price.unit_quantity, rest_to
|
||||||
|
oacounts.each_with_index do |c, i|
|
||||||
|
cunits[i + 1] += c
|
||||||
|
counts[i + 1] += 1 if c > 0
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
oa.save!
|
|
||||||
end
|
end
|
||||||
|
oa.save!
|
||||||
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]
|
if params[:rest_to_tolerance]
|
||||||
|
notice << I18n.t('orders.update_order_amounts.msg2', count: counts[1],
|
||||||
|
units: cunits[1])
|
||||||
|
end
|
||||||
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(', ')
|
||||||
end
|
end
|
||||||
|
|
||||||
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].compact_blank! if params[:order] && params[:order][:article_ids]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,10 +12,10 @@ class SessionsController < ApplicationController
|
||||||
user = User.authenticate(params[:nick], params[:password])
|
user = User.authenticate(params[:nick], params[:password])
|
||||||
if user
|
if user
|
||||||
user.update_attribute(:last_login, Time.now)
|
user.update_attribute(:last_login, Time.now)
|
||||||
login_and_redirect_to_return_to user, :notice => I18n.t('sessions.logged_in')
|
login_and_redirect_to_return_to user, notice: I18n.t('sessions.logged_in')
|
||||||
else
|
else
|
||||||
flash.now.alert = I18n.t(FoodsoftConfig[:use_nick] ? 'sessions.login_invalid_nick' : 'sessions.login_invalid_email')
|
flash.now.alert = I18n.t(FoodsoftConfig[:use_nick] ? 'sessions.login_invalid_nick' : 'sessions.login_invalid_email')
|
||||||
render "new"
|
render 'new'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ class SessionsController < ApplicationController
|
||||||
if FoodsoftConfig[:logout_redirect_url].present?
|
if FoodsoftConfig[:logout_redirect_url].present?
|
||||||
redirect_to FoodsoftConfig[:logout_redirect_url]
|
redirect_to FoodsoftConfig[:logout_redirect_url]
|
||||||
else
|
else
|
||||||
redirect_to login_url, :notice => I18n.t('sessions.logged_out')
|
redirect_to login_url, notice: I18n.t('sessions.logged_out')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -7,21 +7,21 @@ class StockTakingsController < ApplicationController
|
||||||
|
|
||||||
def new
|
def new
|
||||||
@stock_taking = StockTaking.new
|
@stock_taking = StockTaking.new
|
||||||
StockArticle.undeleted.each { |a| @stock_taking.stock_changes.build(:stock_article => a) }
|
StockArticle.undeleted.each { |a| @stock_taking.stock_changes.build(stock_article: a) }
|
||||||
end
|
end
|
||||||
|
|
||||||
def new_on_stock_article_create # See publish/subscribe design pattern in /doc.
|
def new_on_stock_article_create # See publish/subscribe design pattern in /doc.
|
||||||
stock_article = StockArticle.find(params[:stock_article_id])
|
stock_article = StockArticle.find(params[:stock_article_id])
|
||||||
@stock_change = StockChange.new(:stock_article => stock_article)
|
@stock_change = StockChange.new(stock_article: stock_article)
|
||||||
|
|
||||||
render :layout => false
|
render layout: false
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
create!(:notice => I18n.t('stock_takings.create.notice'))
|
create!(notice: I18n.t('stock_takings.create.notice'))
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
update!(:notice => I18n.t('stock_takings.update.notice'))
|
update!(notice: I18n.t('stock_takings.update.notice'))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,57 +7,13 @@ class StockitController < ApplicationController
|
||||||
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.
|
||||||
@stock_article = StockArticle.find(params[:id])
|
@stock_article = StockArticle.find(params[:id])
|
||||||
|
|
||||||
render :layout => false
|
render layout: false
|
||||||
end
|
end
|
||||||
|
|
||||||
def index_on_stock_article_update # See publish/subscribe design pattern in /doc.
|
def index_on_stock_article_update # See publish/subscribe design pattern in /doc.
|
||||||
@stock_article = StockArticle.find(params[:id])
|
@stock_article = StockArticle.find(params[:id])
|
||||||
|
|
||||||
render :layout => false
|
render layout: false
|
||||||
end
|
|
||||||
|
|
||||||
# three possibilites to fill a new_stock_article form
|
|
||||||
# (1) start from blank or use params
|
|
||||||
def new
|
|
||||||
@stock_article = StockArticle.new(params[:stock_article])
|
|
||||||
|
|
||||||
render :layout => false
|
|
||||||
end
|
|
||||||
|
|
||||||
# (2) StockArticle as template
|
|
||||||
def copy
|
|
||||||
@stock_article = StockArticle.find(params[:stock_article_id]).dup
|
|
||||||
|
|
||||||
render :layout => false
|
|
||||||
end
|
|
||||||
|
|
||||||
# (3) non-stock Article as template
|
|
||||||
def derive
|
|
||||||
@stock_article = Article.find(params[:old_article_id]).becomes(StockArticle).dup
|
|
||||||
|
|
||||||
render :layout => false
|
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
|
||||||
@stock_article = StockArticle.new({ quantity: 0 }.merge(params[:stock_article]))
|
|
||||||
@stock_article.save!
|
|
||||||
render :layout => false
|
|
||||||
rescue ActiveRecord::RecordInvalid
|
|
||||||
render :action => 'new', :layout => false
|
|
||||||
end
|
|
||||||
|
|
||||||
def edit
|
|
||||||
@stock_article = StockArticle.find(params[:id])
|
|
||||||
|
|
||||||
render :layout => false
|
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
|
||||||
@stock_article = StockArticle.find(params[:id])
|
|
||||||
@stock_article.update!(params[:stock_article])
|
|
||||||
render :layout => false
|
|
||||||
rescue ActiveRecord::RecordInvalid
|
|
||||||
render :action => 'edit', :layout => false
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
|
@ -65,24 +21,68 @@ class StockitController < ApplicationController
|
||||||
@stock_changes = @stock_article.stock_changes.order('stock_changes.created_at DESC')
|
@stock_changes = @stock_article.stock_changes.order('stock_changes.created_at DESC')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# three possibilites to fill a new_stock_article form
|
||||||
|
# (1) start from blank or use params
|
||||||
|
def new
|
||||||
|
@stock_article = StockArticle.new(params[:stock_article])
|
||||||
|
|
||||||
|
render layout: false
|
||||||
|
end
|
||||||
|
|
||||||
|
# (2) StockArticle as template
|
||||||
|
def copy
|
||||||
|
@stock_article = StockArticle.find(params[:stock_article_id]).dup
|
||||||
|
|
||||||
|
render layout: false
|
||||||
|
end
|
||||||
|
|
||||||
|
# (3) non-stock Article as template
|
||||||
|
def derive
|
||||||
|
@stock_article = Article.find(params[:old_article_id]).becomes(StockArticle).dup
|
||||||
|
|
||||||
|
render layout: false
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
@stock_article = StockArticle.find(params[:id])
|
||||||
|
|
||||||
|
render layout: false
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@stock_article = StockArticle.new({ quantity: 0 }.merge(params[:stock_article]))
|
||||||
|
@stock_article.save!
|
||||||
|
render layout: false
|
||||||
|
rescue ActiveRecord::RecordInvalid
|
||||||
|
render action: 'new', layout: false
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
@stock_article = StockArticle.find(params[:id])
|
||||||
|
@stock_article.update!(params[:stock_article])
|
||||||
|
render layout: false
|
||||||
|
rescue ActiveRecord::RecordInvalid
|
||||||
|
render action: 'edit', layout: false
|
||||||
|
end
|
||||||
|
|
||||||
def show_on_stock_article_update # See publish/subscribe design pattern in /doc.
|
def show_on_stock_article_update # See publish/subscribe design pattern in /doc.
|
||||||
@stock_article = StockArticle.find(params[:id])
|
@stock_article = StockArticle.find(params[:id])
|
||||||
|
|
||||||
render :layout => false
|
render layout: false
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
@stock_article = StockArticle.find(params[:id])
|
@stock_article = StockArticle.find(params[:id])
|
||||||
@stock_article.mark_as_deleted
|
@stock_article.mark_as_deleted
|
||||||
render :layout => false
|
render layout: false
|
||||||
rescue => error
|
rescue StandardError => e
|
||||||
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: e.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)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,7 +9,7 @@ class StylesController < ApplicationController
|
||||||
def foodcoop
|
def foodcoop
|
||||||
css = FoodsoftConfig[:custom_css]
|
css = FoodsoftConfig[:custom_css]
|
||||||
if css.blank?
|
if css.blank?
|
||||||
render body: nil, content_type: 'text/css', status: 404
|
render body: nil, content_type: 'text/css', status: :not_found
|
||||||
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'
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
class SuppliersController < ApplicationController
|
class SuppliersController < ApplicationController
|
||||||
before_action :authenticate_suppliers, :except => [:index, :list]
|
before_action :authenticate_suppliers, except: %i[index list]
|
||||||
helper :deliveries
|
helper :deliveries
|
||||||
|
|
||||||
def index
|
def index
|
||||||
|
@ -24,6 +24,10 @@ class SuppliersController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
@supplier = Supplier.find(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@supplier = Supplier.new(supplier_params)
|
@supplier = Supplier.new(supplier_params)
|
||||||
@supplier.supplier_category ||= SupplierCategory.first
|
@supplier.supplier_category ||= SupplierCategory.first
|
||||||
|
@ -31,21 +35,17 @@ class SuppliersController < ApplicationController
|
||||||
flash[:notice] = I18n.t('suppliers.create.notice')
|
flash[:notice] = I18n.t('suppliers.create.notice')
|
||||||
redirect_to suppliers_path
|
redirect_to suppliers_path
|
||||||
else
|
else
|
||||||
render :action => 'new'
|
render action: 'new'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def edit
|
|
||||||
@supplier = Supplier.find(params[:id])
|
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
def update
|
||||||
@supplier = Supplier.find(params[:id])
|
@supplier = Supplier.find(params[:id])
|
||||||
if @supplier.update(supplier_params)
|
if @supplier.update(supplier_params)
|
||||||
flash[:notice] = I18n.t('suppliers.update.notice')
|
flash[:notice] = I18n.t('suppliers.update.notice')
|
||||||
redirect_to @supplier
|
redirect_to @supplier
|
||||||
else
|
else
|
||||||
render :action => 'edit'
|
render action: 'edit'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -54,8 +54,8 @@ 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 StandardError => 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
|
||||||
|
|
||||||
|
|
|
@ -11,35 +11,33 @@ class TasksController < ApplicationController
|
||||||
@accepted_tasks = Task.accepted_tasks_for(current_user)
|
@accepted_tasks = Task.accepted_tasks_for(current_user)
|
||||||
end
|
end
|
||||||
|
|
||||||
def new
|
|
||||||
@task = Task.new(current_user_id: current_user.id)
|
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
|
||||||
@task = Task.new(current_user_id: current_user.id)
|
|
||||||
@task.created_by = current_user
|
|
||||||
@task.attributes = (task_params)
|
|
||||||
if params[:periodic]
|
|
||||||
@task.periodic_task_group = PeriodicTaskGroup.new
|
|
||||||
end
|
|
||||||
if @task.save
|
|
||||||
@task.periodic_task_group.create_tasks_for_upfront_days if params[:periodic]
|
|
||||||
redirect_to tasks_url, :notice => I18n.t('tasks.create.notice')
|
|
||||||
else
|
|
||||||
render :template => "tasks/new"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@task = Task.find(params[:id])
|
@task = Task.find(params[:id])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
@task = Task.new(current_user_id: current_user.id)
|
||||||
|
end
|
||||||
|
|
||||||
def edit
|
def edit
|
||||||
@task = Task.find(params[:id])
|
@task = Task.find(params[:id])
|
||||||
@periodic = !!params[:periodic]
|
@periodic = !!params[:periodic]
|
||||||
@task.current_user_id = current_user.id
|
@task.current_user_id = current_user.id
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@task = Task.new(current_user_id: current_user.id)
|
||||||
|
@task.created_by = current_user
|
||||||
|
@task.attributes = (task_params)
|
||||||
|
@task.periodic_task_group = PeriodicTaskGroup.new if params[:periodic]
|
||||||
|
if @task.save
|
||||||
|
@task.periodic_task_group.create_tasks_for_upfront_days if params[:periodic]
|
||||||
|
redirect_to tasks_url, notice: I18n.t('tasks.create.notice')
|
||||||
|
else
|
||||||
|
render template: 'tasks/new'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
@task = Task.find(params[:id])
|
@task = Task.find(params[:id])
|
||||||
task_group = @task.periodic_task_group
|
task_group = @task.periodic_task_group
|
||||||
|
@ -50,16 +48,14 @@ class TasksController < ApplicationController
|
||||||
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')
|
||||||
if was_periodic && !@task.periodic?
|
flash[:notice] = I18n.t('tasks.update.notice_converted') if was_periodic && !@task.periodic?
|
||||||
flash[:notice] = I18n.t('tasks.update.notice_converted')
|
|
||||||
end
|
|
||||||
if @task.workgroup
|
if @task.workgroup
|
||||||
redirect_to workgroup_tasks_url(workgroup_id: @task.workgroup_id)
|
redirect_to workgroup_tasks_url(workgroup_id: @task.workgroup_id)
|
||||||
else
|
else
|
||||||
redirect_to tasks_url
|
redirect_to tasks_url
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
render :template => "tasks/edit"
|
render template: 'tasks/edit'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -75,7 +71,7 @@ class TasksController < ApplicationController
|
||||||
end
|
end
|
||||||
task.update_ordergroup_stats(user_ids)
|
task.update_ordergroup_stats(user_ids)
|
||||||
|
|
||||||
redirect_to tasks_url, :notice => I18n.t('tasks.destroy.notice')
|
redirect_to tasks_url, notice: I18n.t('tasks.destroy.notice')
|
||||||
end
|
end
|
||||||
|
|
||||||
# assign current_user to the task and set the assignment to "accepted"
|
# assign current_user to the task and set the assignment to "accepted"
|
||||||
|
@ -85,20 +81,20 @@ class TasksController < ApplicationController
|
||||||
if ass = task.is_assigned?(current_user)
|
if ass = task.is_assigned?(current_user)
|
||||||
ass.update_attribute(:accepted, true)
|
ass.update_attribute(:accepted, true)
|
||||||
else
|
else
|
||||||
task.assignments.create(:user => current_user, :accepted => true)
|
task.assignments.create(user: current_user, accepted: true)
|
||||||
end
|
end
|
||||||
redirect_to user_tasks_path, :notice => I18n.t('tasks.accept.notice')
|
redirect_to user_tasks_path, notice: I18n.t('tasks.accept.notice')
|
||||||
end
|
end
|
||||||
|
|
||||||
# deletes assignment between current_user and given taskcurrent_user_id: current_user.id
|
# deletes assignment between current_user and given taskcurrent_user_id: current_user.id
|
||||||
def reject
|
def reject
|
||||||
Task.find(params[:id]).users.delete(current_user)
|
Task.find(params[:id]).users.delete(current_user)
|
||||||
redirect_to :action => "index"
|
redirect_to action: 'index'
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_done
|
def set_done
|
||||||
Task.find(params[:id]).update_attribute :done, true
|
Task.find(params[:id]).update_attribute :done, true
|
||||||
redirect_to tasks_url, :notice => I18n.t('tasks.set_done.notice')
|
redirect_to tasks_url, notice: I18n.t('tasks.set_done.notice')
|
||||||
end
|
end
|
||||||
|
|
||||||
# Shows all tasks, which are already done
|
# Shows all tasks, which are already done
|
||||||
|
@ -109,9 +105,9 @@ class TasksController < ApplicationController
|
||||||
# shows workgroup (normal group) to edit weekly_tasks_template
|
# shows workgroup (normal group) to edit weekly_tasks_template
|
||||||
def workgroup
|
def workgroup
|
||||||
@group = Group.find(params[:workgroup_id])
|
@group = Group.find(params[:workgroup_id])
|
||||||
if @group.is_a? Ordergroup
|
return unless @group.is_a? Ordergroup
|
||||||
redirect_to tasks_url, :alert => I18n.t('tasks.error_not_found')
|
|
||||||
end
|
redirect_to tasks_url, alert: I18n.t('tasks.error_not_found')
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
|
@ -3,7 +3,7 @@ class UsersController < ApplicationController
|
||||||
def index
|
def index
|
||||||
@users = User.undeleted.natural_search(params[:q])
|
@users = User.undeleted.natural_search(params[:q])
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
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
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
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
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
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
|
||||||
|
|
|
@ -2,7 +2,7 @@ class OrderFax < OrderPdf
|
||||||
BATCH_SIZE = 250
|
BATCH_SIZE = 250
|
||||||
|
|
||||||
def filename
|
def filename
|
||||||
I18n.t('documents.order_fax.filename', :name => order.name, :date => order.ends.to_date) + '.pdf'
|
I18n.t('documents.order_fax.filename', name: order.name, date: order.ends.to_date) + '.pdf'
|
||||||
end
|
end
|
||||||
|
|
||||||
def title
|
def title
|
||||||
|
@ -20,16 +20,18 @@ class OrderFax < OrderPdf
|
||||||
move_down 5
|
move_down 5
|
||||||
text "#{contact[:zip_code]} #{contact[:city]}", size: fontsize(9), align: :right
|
text "#{contact[:zip_code]} #{contact[:city]}", size: fontsize(9), align: :right
|
||||||
move_down 5
|
move_down 5
|
||||||
unless order.supplier.try(:customer_number).blank?
|
if order.supplier.try(:customer_number).present?
|
||||||
text "#{Supplier.human_attribute_name :customer_number}: #{order.supplier[:customer_number]}", size: fontsize(9), align: :right
|
text "#{Supplier.human_attribute_name :customer_number}: #{order.supplier[:customer_number]}",
|
||||||
|
size: fontsize(9), align: :right
|
||||||
move_down 5
|
move_down 5
|
||||||
end
|
end
|
||||||
unless contact[:phone].blank?
|
if contact[:phone].present?
|
||||||
text "#{Supplier.human_attribute_name :phone}: #{contact[:phone]}", size: fontsize(9), align: :right
|
text "#{Supplier.human_attribute_name :phone}: #{contact[:phone]}", size: fontsize(9), align: :right
|
||||||
move_down 5
|
move_down 5
|
||||||
end
|
end
|
||||||
unless contact[:email].blank?
|
if contact[:email].present?
|
||||||
text "#{Supplier.human_attribute_name :email}: #{contact[:email]}", size: fontsize(9), align: :right
|
text "#{Supplier.human_attribute_name :email}: #{contact[:email]}", size: fontsize(9),
|
||||||
|
align: :right
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -38,7 +40,7 @@ class OrderFax < OrderPdf
|
||||||
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
|
||||||
unless order.supplier.try(:fax).blank?
|
if order.supplier.try(:fax).present?
|
||||||
move_down 5
|
move_down 5
|
||||||
text "#{Supplier.human_attribute_name :fax}: #{order.supplier[:fax]}"
|
text "#{Supplier.human_attribute_name :fax}: #{order.supplier[:fax]}"
|
||||||
end
|
end
|
||||||
|
@ -50,7 +52,7 @@ class OrderFax < OrderPdf
|
||||||
move_down 10
|
move_down 10
|
||||||
text "#{Delivery.human_attribute_name :date}:"
|
text "#{Delivery.human_attribute_name :date}:"
|
||||||
move_down 10
|
move_down 10
|
||||||
unless order.supplier.try(:contact_person).blank?
|
if order.supplier.try(:contact_person).present?
|
||||||
text "#{Supplier.human_attribute_name :contact_person}: #{order.supplier[:contact_person]}"
|
text "#{Supplier.human_attribute_name :contact_person}: #{order.supplier[:contact_person]}"
|
||||||
move_down 10
|
move_down 10
|
||||||
end
|
end
|
||||||
|
@ -78,8 +80,8 @@ 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 = %i[top bottom]
|
||||||
table.row(data.length - 1).columns(0).borders = [:top, :bottom, :left]
|
table.row(data.length - 1).columns(0).borders = %i[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),
|
||||||
|
@ -98,7 +100,7 @@ class OrderFax < OrderPdf
|
||||||
.preload(:article, :article_price)
|
.preload(:article, :article_price)
|
||||||
end
|
end
|
||||||
|
|
||||||
def each_order_article
|
def each_order_article(&block)
|
||||||
order_articles.find_each_with_order(batch_size: BATCH_SIZE) { |oa| yield oa }
|
order_articles.find_each_with_order(batch_size: BATCH_SIZE, &block)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,12 +3,12 @@ class OrderMatrix < OrderPdf
|
||||||
PLACEHOLDER_CHAR = 'X'
|
PLACEHOLDER_CHAR = 'X'
|
||||||
|
|
||||||
def filename
|
def filename
|
||||||
I18n.t('documents.order_matrix.filename', :name => @order.name, :date => @order.ends.to_date) + '.pdf'
|
I18n.t('documents.order_matrix.filename', name: @order.name, date: @order.ends.to_date) + '.pdf'
|
||||||
end
|
end
|
||||||
|
|
||||||
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
|
||||||
|
@ -87,7 +87,7 @@ class OrderMatrix < OrderPdf
|
||||||
table.cells.border_width = 0.5
|
table.cells.border_width = 0.5
|
||||||
table.cells.border_color = '666666'
|
table.cells.border_color = '666666'
|
||||||
|
|
||||||
table.row(0).borders = [:bottom, :left]
|
table.row(0).borders = %i[bottom left]
|
||||||
table.row(0).padding = [2, 0, 2, 0]
|
table.row(0).padding = [2, 0, 2, 0]
|
||||||
table.row(1..-1).height = row_height_1
|
table.row(1..-1).height = row_height_1
|
||||||
table.column(0..1).borders = []
|
table.column(0..1).borders = []
|
||||||
|
@ -106,7 +106,7 @@ class OrderMatrix < OrderPdf
|
||||||
table.column(2 + idx).border_width = 2
|
table.column(2 + idx).border_width = 2
|
||||||
end
|
end
|
||||||
|
|
||||||
table.row_colors = ['dddddd', 'ffffff']
|
table.row_colors = %w[dddddd ffffff]
|
||||||
end
|
end
|
||||||
|
|
||||||
first_page = false
|
first_page = false
|
||||||
|
|
|
@ -28,7 +28,11 @@ module Admin::ConfigsHelper
|
||||||
options[:default] = options[:input_html].delete(:value)
|
options[:default] = options[:input_html].delete(:value)
|
||||||
return form.input key, options, &block
|
return form.input key, options, &block
|
||||||
end
|
end
|
||||||
block ||= proc { config_input_field form, key, options.merge(options[:input_html]) } if options[:as] == :select_recurring
|
if options[:as] == :select_recurring
|
||||||
|
block ||= proc {
|
||||||
|
config_input_field form, key, options.merge(options[:input_html])
|
||||||
|
}
|
||||||
|
end
|
||||||
form.input key, options, &block
|
form.input key, options, &block
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -57,11 +61,12 @@ module Admin::ConfigsHelper
|
||||||
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
|
||||||
options[:value] = FoodsoftDateUtil.rule_from(options[:value])
|
options[:value] = FoodsoftDateUtil.rule_from(options[:value])
|
||||||
options[:rules] ||= []
|
options[:rules] ||= []
|
||||||
options[:rules].unshift options[:value] unless options[:value].blank?
|
options[:rules].unshift options[:value] if options[:value].present?
|
||||||
options[:rules].push [I18n.t('recurring_select.not_recurring'), '{}'] if options.delete(:allow_blank) # blank after current value
|
options[:rules].push [I18n.t('recurring_select.not_recurring'), '{}'] if options.delete(:allow_blank) # blank after current value
|
||||||
form.select_recurring key, options.delete(:rules).uniq, options
|
form.select_recurring key, options.delete(:rules).uniq, options
|
||||||
else
|
else
|
||||||
|
@ -73,7 +78,7 @@ module Admin::ConfigsHelper
|
||||||
# @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+).
|
||||||
# @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 = {}, &block)
|
||||||
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,
|
||||||
|
@ -83,9 +88,7 @@ module Admin::ConfigsHelper
|
||||||
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]}", &block)
|
||||||
yield
|
|
||||||
end
|
|
||||||
head + fields
|
head + fields
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -127,7 +130,7 @@ module Admin::ConfigsHelper
|
||||||
# tooltip with help info to the right
|
# tooltip with help info to the right
|
||||||
cfg_path = form.lookup_model_names[1..-1] + [key]
|
cfg_path = form.lookup_model_names[1..-1] + [key]
|
||||||
tooltip = I18n.t("config.hints.#{cfg_path.map(&:to_s).join('.')}", default: '')
|
tooltip = I18n.t("config.hints.#{cfg_path.map(&:to_s).join('.')}", default: '')
|
||||||
unless tooltip.blank?
|
if tooltip.present?
|
||||||
options[:data] ||= {}
|
options[:data] ||= {}
|
||||||
options[:data][:toggle] ||= 'tooltip'
|
options[:data][:toggle] ||= 'tooltip'
|
||||||
options[:data][:placement] ||= 'right'
|
options[:data][:placement] ||= 'right'
|
||||||
|
|
|
@ -2,9 +2,7 @@ module Admin::OrdergroupsHelper
|
||||||
def ordergroup_members_title(ordergroup)
|
def ordergroup_members_title(ordergroup)
|
||||||
s = ''
|
s = ''
|
||||||
s += ordergroup.users.map(&:name).join(', ') if ordergroup.users.any?
|
s += ordergroup.users.map(&:name).join(', ') if ordergroup.users.any?
|
||||||
if ordergroup.contact_person.present?
|
s += "\n" + Ordergroup.human_attribute_name(:contact) + ': ' + ordergroup.contact_person if ordergroup.contact_person.present?
|
||||||
s += "\n" + Ordergroup.human_attribute_name(:contact) + ": " + ordergroup.contact_person
|
|
||||||
end
|
|
||||||
s
|
s
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,7 +4,7 @@ module ApplicationHelper
|
||||||
include PathHelper
|
include PathHelper
|
||||||
|
|
||||||
def format_time(time = Time.now)
|
def format_time(time = Time.now)
|
||||||
I18n.l(time, :format => "%d.%m.%Y %H:%M") unless time.nil?
|
I18n.l(time, format: '%d.%m.%Y %H:%M') unless time.nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
def format_date(time = Time.now)
|
def format_date(time = Time.now)
|
||||||
|
@ -16,7 +16,7 @@ module ApplicationHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def format_datetime_timespec(time, format)
|
def format_datetime_timespec(time, format)
|
||||||
I18n.l(time, :format => format) unless (time.nil? || format.nil?)
|
I18n.l(time, format: format) unless time.nil? || format.nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
def format_currency(amount)
|
def format_currency(amount)
|
||||||
|
@ -26,28 +26,28 @@ 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 && iban.scan(/..?.?.?/).map { |item| content_tag(:span, item, style: "margin-right: 0.5em;") }.join.html_safe
|
iban && 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
|
||||||
|
|
||||||
# Link-collection for per_page-options when using the pagination-plugin
|
# Link-collection for per_page-options when using the pagination-plugin
|
||||||
def items_per_page(options = {})
|
def items_per_page(options = {})
|
||||||
per_page_options = options[:per_page_options] || [20, 50, 100, 500]
|
per_page_options = options[:per_page_options] || [20, 50, 100, 500]
|
||||||
current = options[:current] || @per_page
|
current = options[:current] || @per_page
|
||||||
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)
|
||||||
end
|
end
|
||||||
|
|
||||||
if options[:wrap] == false
|
if options[:wrap] == false
|
||||||
|
@ -63,21 +63,19 @@ module ApplicationHelper
|
||||||
# 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
|
||||||
'sortup'
|
'sortup'
|
||||||
when key + '_reverse' then
|
when key + '_reverse'
|
||||||
'sortdown'
|
'sortdown'
|
||||||
else
|
|
||||||
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]
|
||||||
|
@ -95,14 +93,16 @@ 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| !%w[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,
|
||||||
s = raw "<abbr title='#{desc}'>#{sshort}</abbr>" unless sshort.blank?
|
options.merge({ fallback: true, default: '', count: 2 }))
|
||||||
|
s = raw "<abbr title='#{desc}'>#{sshort}</abbr>" if sshort.present?
|
||||||
end
|
end
|
||||||
s
|
s
|
||||||
end
|
end
|
||||||
|
@ -117,7 +117,7 @@ module ApplicationHelper
|
||||||
# Returns the weekday. 0 is sunday, 1 is monday and so on
|
# Returns the weekday. 0 is sunday, 1 is monday and so on
|
||||||
def weekday(dayNumber)
|
def weekday(dayNumber)
|
||||||
weekdays = I18n.t('date.day_names')
|
weekdays = I18n.t('date.day_names')
|
||||||
return weekdays[dayNumber]
|
weekdays[dayNumber]
|
||||||
end
|
end
|
||||||
|
|
||||||
# to set a title for both the h1-tag and the title in the header
|
# to set a title for both the h1-tag and the title in the header
|
||||||
|
@ -136,13 +136,13 @@ module ApplicationHelper
|
||||||
|
|
||||||
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
|
||||||
|
@ -150,27 +150,29 @@ module ApplicationHelper
|
||||||
# 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')",
|
||||||
:method => :get
|
method: :get
|
||||||
}
|
}
|
||||||
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 = roles.index_with { |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(' ').html_safe
|
roles.map do |r|
|
||||||
|
image_tag("role-#{r}.png", size: '22x22', border: 0, alt: names[r], title: names[r])
|
||||||
|
end.join(' ').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', rel: 'noopener'
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns flash messages html.
|
# Returns flash messages html.
|
||||||
|
@ -186,8 +188,8 @@ module ApplicationHelper
|
||||||
type = :success if type == 'notice'
|
type = :success if type == 'notice'
|
||||||
type = :error if type == 'alert'
|
type = :error if type == 'alert'
|
||||||
text = content_tag(:div,
|
text = content_tag(:div,
|
||||||
content_tag(:button, I18n.t('ui.marks.close').html_safe, :class => "close", "data-dismiss" => "alert") +
|
content_tag(:button, I18n.t('ui.marks.close').html_safe, :class => 'close', 'data-dismiss' => 'alert') +
|
||||||
message, :class => "alert fade in alert-#{type}")
|
message, class: "alert fade in alert-#{type}")
|
||||||
flash_messages << text if message
|
flash_messages << text if message
|
||||||
end
|
end
|
||||||
flash_messages.join("\n").html_safe
|
flash_messages.join("\n").html_safe
|
||||||
|
@ -195,17 +197,17 @@ module ApplicationHelper
|
||||||
|
|
||||||
# render base errors in a form after failed validation
|
# render base errors in a form after failed validation
|
||||||
# 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]
|
||||||
if options[:full] && options[:markup]
|
if options[:full] && options[:markup]
|
||||||
raw "<b>#{h user.nick}</b> (#{h user.first_name} #{h user.last_name})"
|
raw "<b>#{h user.nick}</b> (#{h user.first_name} #{h user.last_name})"
|
||||||
|
@ -216,7 +218,7 @@ module ApplicationHelper
|
||||||
user.nick.nil? ? I18n.t('helpers.application.nick_fallback') : user.nick
|
user.nick.nil? ? I18n.t('helpers.application.nick_fallback') : user.nick
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
"#{user.first_name} #{user.last_name}" + (options[:unique] ? " (\##{user.id})" : '')
|
"#{user.first_name} #{user.last_name}" + (options[:unique] ? " (##{user.id})" : '')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -258,9 +260,9 @@ module ApplicationHelper
|
||||||
|
|
||||||
# @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?
|
return if FoodsoftConfig[:custom_css].blank?
|
||||||
stylesheet_link_tag foodcoop_css_path, media: 'all'
|
|
||||||
end
|
stylesheet_link_tag foodcoop_css_path, media: 'all'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,13 +3,13 @@ module ArticlesHelper
|
||||||
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
|
||||||
|
|
||||||
def row_classes(article)
|
def row_classes(article)
|
||||||
classes = []
|
classes = []
|
||||||
classes << "unavailable" if !article.availability
|
classes << 'unavailable' unless article.availability
|
||||||
classes << "just-updated" if article.recently_updated && article.availability
|
classes << 'just-updated' if article.recently_updated && article.availability
|
||||||
classes.join(" ")
|
classes.join(' ')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,11 +11,11 @@ module DeliveriesHelper
|
||||||
|
|
||||||
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| !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 { |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)
|
||||||
|
@ -23,10 +23,14 @@ module DeliveriesHelper
|
||||||
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?
|
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'
|
||||||
|
end
|
||||||
|
|
||||||
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'), '#',
|
||||||
return output.html_safe
|
class: 'destroy_stock_change btn btn-small'
|
||||||
|
output.html_safe
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,11 +2,11 @@ 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'
|
||||||
'edit_results_by_articles'
|
'edit_results_by_articles'
|
||||||
when 'groups_overview' then
|
when 'groups_overview'
|
||||||
'shared/articles_by/groups'
|
'shared/articles_by/groups'
|
||||||
when 'articles_overview' then
|
when 'articles_overview'
|
||||||
'shared/articles_by/articles'
|
'shared/articles_by/articles'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
module Finance::InvoicesHelper
|
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
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,12 +2,12 @@ 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?
|
if goa.group_order.order.finished? && current_user.role_finance?
|
||||||
result
|
|
||||||
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
|
||||||
|
else
|
||||||
|
result
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
module GroupOrdersHelper
|
module GroupOrdersHelper
|
||||||
def data_to_js(ordering_data)
|
def data_to_js(ordering_data)
|
||||||
ordering_data[:order_articles].map { |id, data|
|
ordering_data[:order_articles].map do |id, data|
|
||||||
[id, data[:price], data[:unit], data[:total_price], data[:others_quantity], data[:others_tolerance], data[:used_quantity], data[:quantity_available]]
|
[id, data[:price], data[:unit], data[:total_price], data[:others_quantity], data[:others_tolerance],
|
||||||
}.map { |row|
|
data[:used_quantity], data[:quantity_available]]
|
||||||
|
end.map do |row|
|
||||||
"addData(#{row.join(', ')});"
|
"addData(#{row.join(', ')});"
|
||||||
}.join("\n")
|
end.join("\n")
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns a link to the page where a group_order can be edited.
|
# Returns a link to the page where a group_order can be edited.
|
||||||
|
@ -14,9 +15,9 @@ module GroupOrdersHelper
|
||||||
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
|
||||||
|
@ -26,7 +27,7 @@ module GroupOrdersHelper
|
||||||
# Return css class names for order result table
|
# Return css class names for order result table
|
||||||
|
|
||||||
def order_article_class_name(quantity, tolerance, result)
|
def order_article_class_name(quantity, tolerance, result)
|
||||||
if (quantity + tolerance > 0)
|
if quantity + tolerance > 0
|
||||||
result > 0 ? 'success' : 'failed'
|
result > 0 ? 'success' : 'failed'
|
||||||
else
|
else
|
||||||
'ignored'
|
'ignored'
|
||||||
|
@ -45,12 +46,12 @@ module GroupOrdersHelper
|
||||||
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';
|
'missing-few'
|
||||||
elsif (quantity_missing == 0)
|
elsif quantity_missing == 0
|
||||||
return ''
|
''
|
||||||
else
|
else
|
||||||
return 'missing-many'
|
'missing-many'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +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].compact_blank.join(' ')})"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -18,7 +18,7 @@ module OrdersHelper
|
||||||
|
|
||||||
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
|
||||||
|
@ -29,13 +29,13 @@ module OrdersHelper
|
||||||
nil
|
nil
|
||||||
else
|
else
|
||||||
units_info = []
|
units_info = []
|
||||||
[:units_to_order, :units_billed, :units_received].map do |unit|
|
%i[units_to_order units_billed units_received].map do |unit|
|
||||||
if n = order_article.send(unit)
|
next unless n = order_article.send(unit)
|
||||||
line = n.to_s + ' '
|
|
||||||
line += pkg_helper(order_article.price, options) + ' ' unless n == 0
|
line = n.to_s + ' '
|
||||||
line += OrderArticle.human_attribute_name("#{unit}_short", count: n)
|
line += pkg_helper(order_article.price, options) + ' ' unless n == 0
|
||||||
units_info << line
|
line += OrderArticle.human_attribute_name("#{unit}_short", count: n)
|
||||||
end
|
units_info << line
|
||||||
end
|
end
|
||||||
units_info.join(', ').html_safe
|
units_info.join(', ').html_safe
|
||||||
end
|
end
|
||||||
|
@ -67,8 +67,8 @@ module OrdersHelper
|
||||||
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 = " ".html_safe
|
c = ' '.html_safe
|
||||||
options[:class] += " icon-only"
|
options[:class] += ' icon-only'
|
||||||
end
|
end
|
||||||
content_tag(options[:tag], c, class: "package #{options[:class]}").html_safe
|
content_tag(options[:tag], c, class: "package #{options[:class]}").html_safe
|
||||||
end
|
end
|
||||||
|
@ -94,11 +94,12 @@ module OrdersHelper
|
||||||
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: '')) do
|
||||||
button_tag(nil, type: :button, class: 'btn unlocker') {
|
button_tag(nil, type: :button, class: 'btn unlocker') {
|
||||||
content_tag(:i, nil, class: 'icon icon-unlock')
|
content_tag(:i, nil, class: 'icon icon-unlock')
|
||||||
} + input_html
|
} + input_html
|
||||||
}
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
input_html.html_safe
|
input_html.html_safe
|
||||||
|
@ -109,18 +110,16 @@ module OrdersHelper
|
||||||
def ordergroup_count(order)
|
def ordergroup_count(order)
|
||||||
group_orders = order.group_orders.includes(:ordergroup)
|
group_orders = order.group_orders.includes(:ordergroup)
|
||||||
txt = "#{group_orders.count} #{Ordergroup.model_name.human count: group_orders.count}"
|
txt = "#{group_orders.count} #{Ordergroup.model_name.human count: group_orders.count}"
|
||||||
if group_orders.count == 0
|
return txt if group_orders.count == 0
|
||||||
return txt
|
|
||||||
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
|
||||||
|
|
||||||
# @param order_or_supplier [Order, Supplier] Order or supplier to link to
|
# @param order_or_supplier [Order, Supplier] Order or supplier to link to
|
||||||
# @return [String] Link to order or supplier, showing its name.
|
# @return [String] Link to order or supplier, showing its name.
|
||||||
def supplier_link(order_or_supplier)
|
def supplier_link(order_or_supplier)
|
||||||
if order_or_supplier.kind_of?(Order) && order_or_supplier.stockit?
|
if order_or_supplier.is_a?(Order) && order_or_supplier.stockit?
|
||||||
link_to(order_or_supplier.name, stock_articles_path).html_safe
|
link_to(order_or_supplier.name, stock_articles_path).html_safe
|
||||||
else
|
else
|
||||||
link_to(@order.supplier.name, supplier_path(@order.supplier)).html_safe
|
link_to(@order.supplier.name, supplier_path(@order.supplier)).html_safe
|
||||||
|
@ -152,7 +151,8 @@ module OrdersHelper
|
||||||
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
|
||||||
link_to t('orders.index.action_receive'), receive_order_path(order), class: "btn#{' btn-success' unless order.received?} #{options[:class]}"
|
link_to t('orders.index.action_receive'), receive_order_path(order),
|
||||||
|
class: "btn#{' btn-success' unless order.received?} #{options[:class]}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
module StockitHelper
|
module StockitHelper
|
||||||
def stock_article_classes(article)
|
def stock_article_classes(article)
|
||||||
class_names = []
|
class_names = []
|
||||||
class_names << "unavailable" if article.quantity_available <= 0
|
class_names << 'unavailable' if article.quantity_available <= 0
|
||||||
class_names.join(" ")
|
class_names.join(' ')
|
||||||
end
|
end
|
||||||
|
|
||||||
def link_to_stock_change_reason(stock_change)
|
def link_to_stock_change_reason(stock_change)
|
||||||
|
@ -17,8 +17,8 @@ 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
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
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')
|
||||||
end.join(", ").html_safe
|
end.join(', ').html_safe
|
||||||
end
|
end
|
||||||
|
|
||||||
# generate colored number of still required users
|
# generate colored number of still required users
|
||||||
def highlighted_required_users(task)
|
def highlighted_required_users(task)
|
||||||
unless task.enough_users_assigned?
|
return if task.enough_users_assigned?
|
||||||
content_tag :span, task.still_required_users, class: 'badge badge-important',
|
|
||||||
title: I18n.t('helpers.tasks.required_users', :count => task.still_required_users)
|
content_tag :span, task.still_required_users, class: 'badge badge-important',
|
||||||
end
|
title: I18n.t('helpers.tasks.required_users', count: task.still_required_users)
|
||||||
end
|
end
|
||||||
|
|
||||||
def task_title(task)
|
def task_title(task)
|
||||||
|
|
|
@ -6,7 +6,7 @@ class DeltaInput < SimpleForm::Inputs::StringInput
|
||||||
options[:data] ||= {}
|
options[:data] ||= {}
|
||||||
options[:data][:delta] ||= 1
|
options[:data][:delta] ||= 1
|
||||||
options[:autocomplete] ||= 'off'
|
options[:autocomplete] ||= 'off'
|
||||||
# TODO get generated id, don't know how yet - `add_default_name_and_id_for_value` might be an option
|
# TODO: get generated id, don't know how yet - `add_default_name_and_id_for_value` might be an option
|
||||||
|
|
||||||
template.content_tag :div, class: 'delta-input input-prepend input-append' do
|
template.content_tag :div, class: 'delta-input input-prepend input-append' do
|
||||||
delta_button(content_tag(:i, nil, class: 'icon icon-minus'), -1, options) +
|
delta_button(content_tag(:i, nil, class: 'icon icon-minus'), -1, options) +
|
||||||
|
|
|
@ -29,7 +29,7 @@ class AppleBar
|
||||||
|
|
||||||
def mean_order_amount_per_job
|
def mean_order_amount_per_job
|
||||||
(1 / @global_avg).round
|
(1 / @global_avg).round
|
||||||
rescue
|
rescue StandardError
|
||||||
0
|
0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -41,14 +41,14 @@ class BankAccountConnector
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@registered_classes = Set.new
|
@registered_classes = Set.new
|
||||||
|
|
||||||
def self.register(klass)
|
def self.register(klass)
|
||||||
@@registered_classes.add klass
|
@registered_classes.add klass
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.find(iban)
|
def self.find(iban)
|
||||||
@@registered_classes.each do |klass|
|
@registered_classes.each do |klass|
|
||||||
return klass if klass.handles(iban)
|
return klass if klass.handles(iban)
|
||||||
end
|
end
|
||||||
nil
|
nil
|
||||||
|
|
|
@ -17,16 +17,16 @@ class BankAccountInformationImporter
|
||||||
ret = 0
|
ret = 0
|
||||||
booked.each do |t|
|
booked.each do |t|
|
||||||
amount = parse_account_information_amount t[:transactionAmount]
|
amount = parse_account_information_amount t[:transactionAmount]
|
||||||
entityName = amount < 0 ? t[:creditorName] : t[:debtorName]
|
entity_name = amount < 0 ? t[:creditorName] : t[:debtorName]
|
||||||
entityAccount = amount < 0 ? t[:creditorAccount] : t[:debtorAccount]
|
entity_account = amount < 0 ? t[:creditorAccount] : t[:debtorAccount]
|
||||||
reference = [t[:endToEndId], t[:remittanceInformationUnstructured]].join("\n").strip
|
reference = [t[:endToEndId], t[:remittanceInformationUnstructured]].join("\n").strip
|
||||||
|
|
||||||
@bank_account.bank_transactions.where(external_id: t[:transactionId]).first_or_create.update({
|
@bank_account.bank_transactions.where(external_id: t[:transactionId]).first_or_create.update({
|
||||||
date: t[:bookingDate],
|
date: t[:bookingDate],
|
||||||
amount: amount,
|
amount: amount,
|
||||||
iban: entityAccount && entityAccount[:iban],
|
iban: entity_account && entity_account[:iban],
|
||||||
reference: reference,
|
reference: reference,
|
||||||
text: entityName,
|
text: entity_name,
|
||||||
receipt: t[:additionalInformation]
|
receipt: t[:additionalInformation]
|
||||||
})
|
})
|
||||||
ret += 1
|
ret += 1
|
||||||
|
@ -34,7 +34,7 @@ class BankAccountInformationImporter
|
||||||
|
|
||||||
balances = (data[:balances] ? data[:balances].map { |b| [b[:balanceType], b[:balanceAmount]] } : []).to_h
|
balances = (data[:balances] ? data[:balances].map { |b| [b[:balanceType], b[:balanceAmount]] } : []).to_h
|
||||||
balance = balances.values.first
|
balance = balances.values.first
|
||||||
%w(closingBooked expected authorised openingBooked interimAvailable forwardAvailable nonInvoiced).each do |type|
|
%w[closingBooked expected authorised openingBooked interimAvailable forwardAvailable nonInvoiced].each do |type|
|
||||||
value = balances[type]
|
value = balances[type]
|
||||||
if value
|
if value
|
||||||
balance = value
|
balance = value
|
||||||
|
|
|
@ -10,66 +10,68 @@ module DateTimeAttributeValidate
|
||||||
super
|
super
|
||||||
|
|
||||||
attributes.each do |attribute|
|
attributes.each do |attribute|
|
||||||
validate -> { self.send("#{attribute}_datetime_value_valid") }
|
validate -> { send("#{attribute}_datetime_value_valid") }
|
||||||
|
|
||||||
# allow resetting the field to nil
|
# allow resetting the field to nil
|
||||||
before_validation do
|
before_validation do
|
||||||
if self.instance_variable_get("@#{attribute}_is_set")
|
if instance_variable_get("@#{attribute}_is_set")
|
||||||
date = self.instance_variable_get("@#{attribute}_date_value")
|
date = instance_variable_get("@#{attribute}_date_value")
|
||||||
time = self.instance_variable_get("@#{attribute}_time_value")
|
time = instance_variable_get("@#{attribute}_time_value")
|
||||||
if date.blank? && time.blank?
|
send("#{attribute}=", nil) if date.blank? && time.blank?
|
||||||
self.send("#{attribute}=", nil)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# remember old date and time values
|
# remember old date and time values
|
||||||
define_method("#{attribute}_date_value=") do |val|
|
define_method("#{attribute}_date_value=") do |val|
|
||||||
self.instance_variable_set("@#{attribute}_is_set", true)
|
instance_variable_set("@#{attribute}_is_set", true)
|
||||||
self.instance_variable_set("@#{attribute}_date_value", val)
|
instance_variable_set("@#{attribute}_date_value", val)
|
||||||
begin
|
begin
|
||||||
self.send("#{attribute}_date=", val)
|
send("#{attribute}_date=", val)
|
||||||
rescue
|
rescue StandardError
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
define_method("#{attribute}_time_value=") do |val|
|
define_method("#{attribute}_time_value=") do |val|
|
||||||
self.instance_variable_set("@#{attribute}_is_set", true)
|
instance_variable_set("@#{attribute}_is_set", true)
|
||||||
self.instance_variable_set("@#{attribute}_time_value", val)
|
instance_variable_set("@#{attribute}_time_value", val)
|
||||||
begin
|
begin
|
||||||
self.send("#{attribute}_time=", val)
|
send("#{attribute}_time=", val)
|
||||||
rescue
|
rescue StandardError
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# fallback to field when values are not set
|
# fallback to field when values are not set
|
||||||
define_method("#{attribute}_date_value") do
|
define_method("#{attribute}_date_value") do
|
||||||
self.instance_variable_get("@#{attribute}_date_value") || self.send("#{attribute}_date").try { |e| e.strftime('%Y-%m-%d') }
|
instance_variable_get("@#{attribute}_date_value") || send("#{attribute}_date").try do |e|
|
||||||
|
e.strftime('%Y-%m-%d')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
define_method("#{attribute}_time_value") do
|
define_method("#{attribute}_time_value") do
|
||||||
self.instance_variable_get("@#{attribute}_time_value") || self.send("#{attribute}_time").try { |e| e.strftime('%H:%M') }
|
instance_variable_get("@#{attribute}_time_value") || send("#{attribute}_time").try do |e|
|
||||||
|
e.strftime('%H:%M')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# validate date and time
|
# validate date and time
|
||||||
define_method("#{attribute}_datetime_value_valid") do
|
define_method("#{attribute}_datetime_value_valid") do
|
||||||
date = self.instance_variable_get("@#{attribute}_date_value")
|
date = instance_variable_get("@#{attribute}_date_value")
|
||||||
unless date.blank? || begin
|
unless date.blank? || begin
|
||||||
Date.parse(date)
|
Date.parse(date)
|
||||||
rescue
|
rescue StandardError
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
errors.add(attribute, "is not a valid date") # @todo I18n
|
errors.add(attribute, 'is not a valid date') # @todo I18n
|
||||||
end
|
end
|
||||||
time = self.instance_variable_get("@#{attribute}_time_value")
|
time = instance_variable_get("@#{attribute}_time_value")
|
||||||
unless time.blank? || begin
|
unless time.blank? || begin
|
||||||
Time.parse(time)
|
Time.parse(time)
|
||||||
rescue
|
rescue StandardError
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
errors.add(attribute, "is not a valid time") # @todo I18n
|
errors.add(attribute, 'is not a valid time') # @todo I18n
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -14,7 +14,7 @@ module Foodsoft
|
||||||
cattr_accessor :variables
|
cattr_accessor :variables
|
||||||
|
|
||||||
# Hash of variables. Note that keys are Strings.
|
# Hash of variables. Note that keys are Strings.
|
||||||
@@variables = {
|
@variables = {
|
||||||
'scope' => -> { FoodsoftConfig.scope },
|
'scope' => -> { FoodsoftConfig.scope },
|
||||||
'name' => -> { FoodsoftConfig[:name] },
|
'name' => -> { FoodsoftConfig[:name] },
|
||||||
'contact.street' => -> { FoodsoftConfig[:contact][:street] },
|
'contact.street' => -> { FoodsoftConfig[:contact][:street] },
|
||||||
|
@ -39,13 +39,13 @@ module Foodsoft
|
||||||
'supplier_count' => -> { Supplier.undeleted.count },
|
'supplier_count' => -> { Supplier.undeleted.count },
|
||||||
'active_supplier_count' => -> { active_supplier_count },
|
'active_supplier_count' => -> { active_supplier_count },
|
||||||
'active_suppliers' => -> { active_suppliers },
|
'active_suppliers' => -> { active_suppliers },
|
||||||
'first_order_date' => -> { I18n.l Order.first.try { |o| o.starts.to_date } }
|
'first_order_date' => -> { I18n.l(Order.first.try { |o| o.starts.to_date }) }
|
||||||
}
|
}
|
||||||
|
|
||||||
# Return expanded variable
|
# Return expanded variable
|
||||||
# @return [String] Expanded variable
|
# @return [String] Expanded variable
|
||||||
def self.get(var)
|
def self.get(var)
|
||||||
s = @@variables[var.to_s]
|
s = @variables[var.to_s]
|
||||||
s.respond_to?(:call) ? s.call : s.to_s
|
s.respond_to?(:call) ? s.call : s.to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ module Foodsoft
|
||||||
# @return [String] Expanded string
|
# @return [String] Expanded string
|
||||||
def self.expand(str, options = {})
|
def self.expand(str, options = {})
|
||||||
str.gsub(/{{([._a-zA-Z0-9]+)}}/) do
|
str.gsub(/{{([._a-zA-Z0-9]+)}}/) do
|
||||||
options[::Regexp.last_match(1)] || self.get(::Regexp.last_match(1))
|
options[::Regexp.last_match(1)] || get(::Regexp.last_match(1))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ class FoodsoftConfig
|
||||||
# Load initial config from development or production
|
# Load initial config from development or production
|
||||||
set_config Rails.env
|
set_config Rails.env
|
||||||
# Overwrite scope to have a better namescope than 'production'
|
# Overwrite scope to have a better namescope than 'production'
|
||||||
self.scope = config[:default_scope] or raise "No default_scope is set"
|
self.scope = config[:default_scope] or raise 'No default_scope is set'
|
||||||
# Set defaults for backward-compatibility
|
# Set defaults for backward-compatibility
|
||||||
set_missing
|
set_missing
|
||||||
# Make sure relevant configuration is applied, also in single coops mode,
|
# Make sure relevant configuration is applied, also in single coops mode,
|
||||||
|
@ -79,7 +79,7 @@ class FoodsoftConfig
|
||||||
end
|
end
|
||||||
|
|
||||||
def init_mailing
|
def init_mailing
|
||||||
[:protocol, :host, :port, :script_name].each do |k|
|
%i[protocol host port script_name].each do |k|
|
||||||
ActionMailer::Base.default_url_options[k] = self[k] if self[k]
|
ActionMailer::Base.default_url_options[k] = self[k] if self[k]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -117,7 +117,7 @@ class FoodsoftConfig
|
||||||
# @return [Object] Value of the key.
|
# @return [Object] Value of the key.
|
||||||
def [](key)
|
def [](key)
|
||||||
if RailsSettings::CachedSettings.table_exists? && allowed_key?(key)
|
if RailsSettings::CachedSettings.table_exists? && allowed_key?(key)
|
||||||
value = RailsSettings::CachedSettings["foodcoop.#{self.scope}.#{key}"]
|
value = RailsSettings::CachedSettings["foodcoop.#{scope}.#{key}"]
|
||||||
value = config[key] if value.nil?
|
value = config[key] if value.nil?
|
||||||
value
|
value
|
||||||
else
|
else
|
||||||
|
@ -139,20 +139,20 @@ class FoodsoftConfig
|
||||||
if config[key] == value || (config[key].nil? && value == false)
|
if config[key] == value || (config[key].nil? && value == false)
|
||||||
# delete (ok if it was already deleted)
|
# delete (ok if it was already deleted)
|
||||||
begin
|
begin
|
||||||
RailsSettings::CachedSettings.destroy "foodcoop.#{self.scope}.#{key}"
|
RailsSettings::CachedSettings.destroy "foodcoop.#{scope}.#{key}"
|
||||||
rescue RailsSettings::Settings::SettingNotFound
|
rescue RailsSettings::Settings::SettingNotFound
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
# or store
|
# or store
|
||||||
RailsSettings::CachedSettings["foodcoop.#{self.scope}.#{key}"] = value
|
RailsSettings::CachedSettings["foodcoop.#{scope}.#{key}"] = value
|
||||||
end
|
end
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
# @return [Array<String>] Configuration keys that are set (either in +app_config.yml+ or database).
|
# @return [Array<String>] Configuration keys that are set (either in +app_config.yml+ or database).
|
||||||
def keys
|
def keys
|
||||||
keys = RailsSettings::CachedSettings.get_all("foodcoop.#{self.scope}.").try(:keys) || []
|
keys = RailsSettings::CachedSettings.get_all("foodcoop.#{scope}.").try(:keys) || []
|
||||||
keys.map! { |k| k.gsub(/^foodcoop\.#{self.scope}\./, '') }
|
keys.map! { |k| k.gsub(/^foodcoop\.#{scope}\./, '') }
|
||||||
keys += config.keys
|
keys += config.keys
|
||||||
keys.map(&:to_s).uniq
|
keys.map(&:to_s).uniq
|
||||||
end
|
end
|
||||||
|
@ -181,10 +181,10 @@ class FoodsoftConfig
|
||||||
# @return [Boolean] Whether this key may be set in the database
|
# @return [Boolean] Whether this key may be set in the database
|
||||||
def allowed_key?(key)
|
def allowed_key?(key)
|
||||||
# fast check for keys without nesting
|
# fast check for keys without nesting
|
||||||
if self.config[:protected].include? key
|
if config[:protected].include? key
|
||||||
!self.config[:protected][key]
|
!config[:protected][key]
|
||||||
else
|
else
|
||||||
!self.config[:protected][:all]
|
!config[:protected][:all]
|
||||||
end
|
end
|
||||||
# @todo allow to check nested keys as well
|
# @todo allow to check nested keys as well
|
||||||
end
|
end
|
||||||
|
@ -287,7 +287,9 @@ class FoodsoftConfig
|
||||||
def normalize_value(value)
|
def normalize_value(value)
|
||||||
value = value.map { |v| normalize_value(v) } if value.is_a? Array
|
value = value.map { |v| normalize_value(v) } if value.is_a? Array
|
||||||
if value.is_a? Hash
|
if value.is_a? Hash
|
||||||
value = ActiveSupport::HashWithIndifferentAccess[value.to_a.map { |a| [a[0], normalize_value(a[1])] }]
|
value = ActiveSupport::HashWithIndifferentAccess[value.to_a.map do |a|
|
||||||
|
[a[0], normalize_value(a[1])]
|
||||||
|
end]
|
||||||
end
|
end
|
||||||
case value
|
case value
|
||||||
when 'true' then true
|
when 'true' then true
|
||||||
|
|
|
@ -8,26 +8,24 @@ module FoodsoftDateUtil
|
||||||
# @todo handle ical parse errors
|
# @todo handle ical parse errors
|
||||||
occ = begin
|
occ = begin
|
||||||
schedule.next_occurrence(from).to_time
|
schedule.next_occurrence(from).to_time
|
||||||
rescue
|
rescue StandardError
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if options && options[:time] && occ
|
occ = occ.beginning_of_day.advance(seconds: Time.parse(options[:time]).seconds_since_midnight) if options && options[:time] && occ
|
||||||
occ = occ.beginning_of_day.advance(seconds: Time.parse(options[:time]).seconds_since_midnight)
|
|
||||||
end
|
|
||||||
occ
|
occ
|
||||||
end
|
end
|
||||||
|
|
||||||
# @param p [String, Symbol, Hash, IceCube::Rule] What to return a rule from.
|
# @param rule [String, Symbol, Hash, IceCube::Rule] What to return a rule from.
|
||||||
# @return [IceCube::Rule] Recurring rule
|
# @return [IceCube::Rule] Recurring rule
|
||||||
def self.rule_from(p)
|
def self.rule_from(rule)
|
||||||
case p
|
case rule
|
||||||
when String
|
when String
|
||||||
IceCube::Rule.from_ical(p)
|
IceCube::Rule.from_ical(rule)
|
||||||
when Hash
|
when Hash
|
||||||
IceCube::Rule.from_hash(p)
|
IceCube::Rule.from_hash(rule)
|
||||||
else
|
else
|
||||||
p
|
rule
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,17 +7,17 @@ class FoodsoftFile
|
||||||
SpreadsheetFile.parse file, options do |row, row_index|
|
SpreadsheetFile.parse file, options do |row, row_index|
|
||||||
next if row[2].blank?
|
next if row[2].blank?
|
||||||
|
|
||||||
article = { :order_number => row[1],
|
article = { order_number: row[1],
|
||||||
:name => row[2],
|
name: row[2],
|
||||||
:note => row[3],
|
note: row[3],
|
||||||
:manufacturer => row[4],
|
manufacturer: row[4],
|
||||||
:origin => row[5],
|
origin: row[5],
|
||||||
:unit => row[6],
|
unit: row[6],
|
||||||
:price => row[7],
|
price: row[7],
|
||||||
:tax => row[8],
|
tax: row[8],
|
||||||
:deposit => (row[9].nil? ? "0" : row[9]),
|
deposit: (row[9].nil? ? '0' : row[9]),
|
||||||
:unit_quantity => row[10],
|
unit_quantity: row[10],
|
||||||
:article_category => row[13] }
|
article_category: row[13] }
|
||||||
status = row[0] && row[0].strip.downcase == 'x' ? :outlisted : nil
|
status = row[0] && row[0].strip.downcase == 'x' ? :outlisted : nil
|
||||||
yield status, article, row_index
|
yield status, article, row_index
|
||||||
end
|
end
|
||||||
|
|
|
@ -23,8 +23,8 @@ class FoodsoftMailReceiver < MidiSmtpServer::Smtpd
|
||||||
recipient = rcpt_to.gsub(/^\s*<\s*(.*)\s*>\s*$/, '\1')
|
recipient = rcpt_to.gsub(/^\s*<\s*(.*)\s*>\s*$/, '\1')
|
||||||
@handlers << self.class.find_handler(recipient)
|
@handlers << self.class.find_handler(recipient)
|
||||||
rcpt_to
|
rcpt_to
|
||||||
rescue => error
|
rescue StandardError => e
|
||||||
logger.info("Can not accept mail for '#{rcpt_to}': #{error}")
|
logger.info("Can not accept mail for '#{rcpt_to}': #{e}")
|
||||||
raise MidiSmtpServer::Smtpd550Exception
|
raise MidiSmtpServer::Smtpd550Exception
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -32,16 +32,16 @@ class FoodsoftMailReceiver < MidiSmtpServer::Smtpd
|
||||||
@handlers.each do |handler|
|
@handlers.each do |handler|
|
||||||
handler.call(ctx[:message][:data])
|
handler.call(ctx[:message][:data])
|
||||||
end
|
end
|
||||||
rescue => error
|
rescue StandardError => e
|
||||||
ExceptionNotifier.notify_exception(error, data: ctx)
|
ExceptionNotifier.notify_exception(e, data: ctx)
|
||||||
raise error
|
raise e
|
||||||
ensure
|
ensure
|
||||||
@handlers.clear
|
@handlers.clear
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.find_handler(recipient)
|
def self.find_handler(recipient)
|
||||||
m = /(?<foodcoop>[^@.]+)\.(?<address>[^@]+)(@(?<hostname>[^@]+))?/.match recipient
|
m = /(?<foodcoop>[^@.]+)\.(?<address>[^@]+)(@(?<hostname>[^@]+))?/.match recipient
|
||||||
raise "recipient is missing or has an invalid format" if m.nil?
|
raise 'recipient is missing or has an invalid format' if m.nil?
|
||||||
raise "Foodcoop '#{m[:foodcoop]}' could not be found" unless FoodsoftConfig.allowed_foodcoop? m[:foodcoop]
|
raise "Foodcoop '#{m[:foodcoop]}' could not be found" unless FoodsoftConfig.allowed_foodcoop? m[:foodcoop]
|
||||||
|
|
||||||
FoodsoftConfig.select_multifoodcoop m[:foodcoop]
|
FoodsoftConfig.select_multifoodcoop m[:foodcoop]
|
||||||
|
@ -53,6 +53,6 @@ class FoodsoftMailReceiver < MidiSmtpServer::Smtpd
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
raise "invalid format for recipient"
|
raise 'invalid format for recipient'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -14,7 +14,7 @@ class OrderCsv < RenderCsv
|
||||||
end
|
end
|
||||||
|
|
||||||
def data
|
def data
|
||||||
@object.order_articles.ordered.includes([:article, :article_price]).all.map do |oa|
|
@object.order_articles.ordered.includes(%i[article article_price]).all.map do |oa|
|
||||||
yield [
|
yield [
|
||||||
oa.units_to_order,
|
oa.units_to_order,
|
||||||
oa.article.order_number,
|
oa.article.order_number,
|
||||||
|
|
|
@ -55,7 +55,7 @@ class OrderPdf < RenderPdf
|
||||||
end
|
end
|
||||||
|
|
||||||
def group_order_article_quantity_with_tolerance(goa)
|
def group_order_article_quantity_with_tolerance(goa)
|
||||||
goa.tolerance > 0 ? "#{goa.quantity} + #{goa.tolerance}" : "#{goa.quantity}"
|
goa.tolerance > 0 ? "#{goa.quantity} + #{goa.tolerance}" : goa.quantity.to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
def group_order_article_result(goa)
|
def group_order_article_result(goa)
|
||||||
|
@ -88,7 +88,7 @@ class OrderPdf < RenderPdf
|
||||||
.pluck('groups.name', 'SUM(group_orders.price)', 'ordergroup_id', 'SUM(group_orders.transport)')
|
.pluck('groups.name', 'SUM(group_orders.price)', 'ordergroup_id', 'SUM(group_orders.transport)')
|
||||||
|
|
||||||
result.map do |item|
|
result.map do |item|
|
||||||
[item.first || stock_ordergroup_name] + item[1..-1]
|
[item.first || stock_ordergroup_name] + item[1..]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ class OrderPdf < RenderPdf
|
||||||
def each_ordergroup_batch(batch_size)
|
def each_ordergroup_batch(batch_size)
|
||||||
offset = 0
|
offset = 0
|
||||||
|
|
||||||
while true
|
loop do
|
||||||
go_records = ordergroups(offset, batch_size)
|
go_records = ordergroups(offset, batch_size)
|
||||||
|
|
||||||
break unless go_records.any?
|
break unless go_records.any?
|
||||||
|
@ -136,7 +136,7 @@ class OrderPdf < RenderPdf
|
||||||
group_order_articles(ordergroup)
|
group_order_articles(ordergroup)
|
||||||
.includes(order_article: { article: [:supplier] })
|
.includes(order_article: { article: [:supplier] })
|
||||||
.order('suppliers.name, articles.name')
|
.order('suppliers.name, articles.name')
|
||||||
.preload(order_article: [:article_price, :order])
|
.preload(order_article: %i[article_price order])
|
||||||
.each(&block)
|
.each(&block)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -8,23 +8,19 @@ class OrderTxt
|
||||||
def to_txt
|
def to_txt
|
||||||
supplier = @order.supplier
|
supplier = @order.supplier
|
||||||
contact = FoodsoftConfig[:contact].symbolize_keys
|
contact = FoodsoftConfig[:contact].symbolize_keys
|
||||||
text = I18n.t('orders.fax.heading', :name => FoodsoftConfig[:name])
|
text = I18n.t('orders.fax.heading', name: FoodsoftConfig[:name])
|
||||||
text += "\n#{Supplier.human_attribute_name(:customer_number)}: #{supplier.customer_number}" unless supplier.customer_number.blank?
|
text += "\n#{Supplier.human_attribute_name(:customer_number)}: #{supplier.customer_number}" if supplier.customer_number.present?
|
||||||
text += "\n" + I18n.t('orders.fax.delivery_day')
|
text += "\n" + I18n.t('orders.fax.delivery_day')
|
||||||
text += "\n\n#{supplier.name}\n#{supplier.address}\n#{Supplier.human_attribute_name(:fax)}: #{supplier.fax}\n\n"
|
text += "\n\n#{supplier.name}\n#{supplier.address}\n#{Supplier.human_attribute_name(:fax)}: #{supplier.fax}\n\n"
|
||||||
text += "****** " + I18n.t('orders.fax.to_address') + "\n\n"
|
text += '****** ' + I18n.t('orders.fax.to_address') + "\n\n"
|
||||||
text += "#{FoodsoftConfig[:name]}\n#{contact[:street]}\n#{contact[:zip_code]} #{contact[:city]}\n\n"
|
text += "#{FoodsoftConfig[:name]}\n#{contact[:street]}\n#{contact[:zip_code]} #{contact[:city]}\n\n"
|
||||||
text += "****** " + I18n.t('orders.fax.articles') + "\n\n"
|
text += '****** ' + I18n.t('orders.fax.articles') + "\n\n"
|
||||||
text += format("%8s %8s %s\n", I18n.t('orders.fax.number'), I18n.t('orders.fax.amount'), I18n.t('orders.fax.name'))
|
text += format("%8s %8s %s\n", I18n.t('orders.fax.number'), I18n.t('orders.fax.amount'),
|
||||||
|
I18n.t('orders.fax.name'))
|
||||||
# now display all ordered articles
|
# now display all ordered articles
|
||||||
@order.order_articles.ordered.includes([:article, :article_price]).each do |oa|
|
@order.order_articles.ordered.includes(%i[article article_price]).each do |oa|
|
||||||
text += format("%8s %8d %s\n", oa.article.order_number, oa.units_to_order.to_i, oa.article.name)
|
text += format("%8s %8d %s\n", oa.article.order_number, oa.units_to_order.to_i, oa.article.name)
|
||||||
end
|
end
|
||||||
text
|
text
|
||||||
end
|
end
|
||||||
|
|
||||||
# Helper method to test pdf via rails console: OrderTxt.new(order).save_tmp
|
|
||||||
def save_tmp
|
|
||||||
File.write("#{Rails.root}/tmp/#{self.class.to_s.underscore}.txt", to_csv.force_encoding("UTF-8"))
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -13,7 +13,7 @@ class RenderCsv
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_csv
|
def to_csv
|
||||||
options = @options.select { |k| %w(col_sep row_sep).include? k.to_s }
|
options = @options.select { |k| %w[col_sep row_sep].include? k.to_s }
|
||||||
ret = CSV.generate options do |csv|
|
ret = CSV.generate options do |csv|
|
||||||
if h = header
|
if h = header
|
||||||
csv << h
|
csv << h
|
||||||
|
@ -31,12 +31,6 @@ class RenderCsv
|
||||||
yield []
|
yield []
|
||||||
end
|
end
|
||||||
|
|
||||||
# Helper method to test pdf via rails console: OrderCsv.new(order).save_tmp
|
|
||||||
def save_tmp
|
|
||||||
encoding = @options[:encoding] || 'UTF-8'
|
|
||||||
File.write("#{Rails.root}/tmp/#{self.class.to_s.underscore}.csv", to_csv.force_encoding(encoding))
|
|
||||||
end
|
|
||||||
|
|
||||||
# XXX disable unit to avoid encoding problems, both in unit and whitespace. Also allows computations in spreadsheet.
|
# XXX disable unit to avoid encoding problems, both in unit and whitespace. Also allows computations in spreadsheet.
|
||||||
def number_to_currency(number, options = {})
|
def number_to_currency(number, options = {})
|
||||||
super(number, options.merge({ unit: '' }))
|
super(number, options.merge({ unit: '' }))
|
||||||
|
|
|
@ -28,9 +28,9 @@ class RotatedCell < Prawn::Table::Cell::Text
|
||||||
with_font { (@pdf.width_of(@content, options) + padding_top + padding_bottom) * tan_rotation }
|
with_font { (@pdf.width_of(@content, options) + padding_top + padding_bottom) * tan_rotation }
|
||||||
end
|
end
|
||||||
|
|
||||||
def draw_borders(pt)
|
def draw_borders(point)
|
||||||
@pdf.mask(:line_width, :stroke_color) do
|
@pdf.mask(:line_width, :stroke_color) do
|
||||||
x, y = pt
|
x, y = point
|
||||||
from = [[x - skew, y + (border_top_width / 2.0)],
|
from = [[x - skew, y + (border_top_width / 2.0)],
|
||||||
to = [x, y - height - (border_bottom_width / 2.0)]]
|
to = [x, y - height - (border_bottom_width / 2.0)]]
|
||||||
|
|
||||||
|
@ -118,11 +118,6 @@ class RenderPdf < Prawn::Document
|
||||||
render # Render pdf
|
render # Render pdf
|
||||||
end
|
end
|
||||||
|
|
||||||
# Helper method to test pdf via rails console: OrderByGroups.new(order).save_tmp
|
|
||||||
def save_tmp
|
|
||||||
File.write("#{Rails.root}/tmp/#{self.class.to_s.underscore}.pdf", to_pdf.force_encoding("UTF-8"))
|
|
||||||
end
|
|
||||||
|
|
||||||
# @todo avoid underscore instead of unicode whitespace in pdf :/
|
# @todo avoid underscore instead of unicode whitespace in pdf :/
|
||||||
def number_to_currency(number, options = {})
|
def number_to_currency(number, options = {})
|
||||||
super(number, options).gsub("\u202f", ' ') if number
|
super(number, options).gsub("\u202f", ' ') if number
|
||||||
|
@ -148,8 +143,8 @@ class RenderPdf < Prawn::Document
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def fontsize(n)
|
def fontsize(size)
|
||||||
n
|
size
|
||||||
end
|
end
|
||||||
|
|
||||||
# return whether pagebreak or vertical whitespace is used for breaks
|
# return whether pagebreak or vertical whitespace is used for breaks
|
||||||
|
|
|
@ -19,9 +19,9 @@ class TokenVerifier < ActiveSupport::MessageVerifier
|
||||||
raise InvalidPrefix unless r[1] == @_prefix
|
raise InvalidPrefix unless r[1] == @_prefix
|
||||||
|
|
||||||
# return original message
|
# return original message
|
||||||
if r.length > 2
|
return unless r.length > 2
|
||||||
r[2]
|
|
||||||
end
|
r[2]
|
||||||
end
|
end
|
||||||
|
|
||||||
class InvalidMessage < ActiveSupport::MessageVerifier::InvalidSignature; end
|
class InvalidMessage < ActiveSupport::MessageVerifier::InvalidSignature; end
|
||||||
|
|
|
@ -81,7 +81,7 @@ class Mailer < ActionMailer::Base
|
||||||
|
|
||||||
add_order_result_attachments order, options
|
add_order_result_attachments order, options
|
||||||
|
|
||||||
subject = I18n.t('mailer.order_result_supplier.subject', :name => order.supplier.name)
|
subject = I18n.t('mailer.order_result_supplier.subject', name: order.supplier.name)
|
||||||
subject += " (#{I18n.t('activerecord.attributes.order.pickup')}: #{format_date(order.pickup)})" if order.pickup
|
subject += " (#{I18n.t('activerecord.attributes.order.pickup')}: #{format_date(order.pickup)})" if order.pickup
|
||||||
|
|
||||||
mail to: order.supplier.email,
|
mail to: order.supplier.email,
|
||||||
|
@ -122,10 +122,11 @@ class Mailer < ActionMailer::Base
|
||||||
|
|
||||||
if args[:from].is_a? User
|
if args[:from].is_a? User
|
||||||
args[:reply_to] ||= args[:from]
|
args[:reply_to] ||= args[:from]
|
||||||
args[:from] = format_address(FoodsoftConfig[:email_sender], I18n.t('mailer.from_via_foodsoft', name: show_user(args[:from])))
|
args[:from] =
|
||||||
|
format_address(FoodsoftConfig[:email_sender], I18n.t('mailer.from_via_foodsoft', name: show_user(args[:from])))
|
||||||
end
|
end
|
||||||
|
|
||||||
[:bcc, :cc, :reply_to, :sender, :to].each do |k|
|
%i[bcc cc reply_to sender to].each do |k|
|
||||||
user = args[k]
|
user = args[k]
|
||||||
args[k] = format_address(user.email, show_user(user)) if user.is_a? User
|
args[k] = format_address(user.email, show_user(user)) if user.is_a? User
|
||||||
end
|
end
|
||||||
|
@ -145,21 +146,21 @@ class Mailer < ActionMailer::Base
|
||||||
|
|
||||||
def self.deliver_now_with_user_locale(user, &block)
|
def self.deliver_now_with_user_locale(user, &block)
|
||||||
I18n.with_locale(user.settings['profile']['language']) do
|
I18n.with_locale(user.settings['profile']['language']) do
|
||||||
self.deliver_now(&block)
|
deliver_now(&block)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.deliver_now_with_default_locale(&block)
|
def self.deliver_now_with_default_locale(&block)
|
||||||
I18n.with_locale(FoodsoftConfig[:default_locale]) do
|
I18n.with_locale(FoodsoftConfig[:default_locale]) do
|
||||||
self.deliver_now(&block)
|
deliver_now(&block)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.deliver_now
|
def self.deliver_now
|
||||||
message = yield
|
message = yield
|
||||||
message.deliver_now
|
message.deliver_now
|
||||||
rescue => error
|
rescue StandardError => e
|
||||||
MailDeliveryStatus.create email: message.to[0], message: error.message
|
MailDeliveryStatus.create email: message.to[0], message: e.message
|
||||||
end
|
end
|
||||||
|
|
||||||
# separate method to allow plugins to mess with the attachments
|
# separate method to allow plugins to mess with the attachments
|
||||||
|
@ -169,8 +170,7 @@ class Mailer < ActionMailer::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
# separate method to allow plugins to mess with the text
|
# separate method to allow plugins to mess with the text
|
||||||
def additonal_welcome_text(user)
|
def additonal_welcome_text(user); end
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ class Article < ApplicationRecord
|
||||||
belongs_to :supplier
|
belongs_to :supplier
|
||||||
# @!attribute article_prices
|
# @!attribute article_prices
|
||||||
# @return [Array<ArticlePrice>] Price history (current price first).
|
# @return [Array<ArticlePrice>] Price history (current price first).
|
||||||
has_many :article_prices, -> { order("created_at DESC") }
|
has_many :article_prices, -> { order('created_at DESC') }
|
||||||
# @!attribute order_articles
|
# @!attribute order_articles
|
||||||
# @return [Array<OrderArticle>] Order articles for this article.
|
# @return [Array<OrderArticle>] Order articles for this article.
|
||||||
has_many :order_articles
|
has_many :order_articles
|
||||||
|
@ -60,16 +60,16 @@ class Article < ApplicationRecord
|
||||||
scope :not_in_stock, -> { where(type: nil) }
|
scope :not_in_stock, -> { where(type: nil) }
|
||||||
|
|
||||||
# Validations
|
# Validations
|
||||||
validates_presence_of :name, :unit, :price, :tax, :deposit, :unit_quantity, :supplier_id, :article_category
|
validates :name, :unit, :price, :tax, :deposit, :unit_quantity, :supplier_id, :article_category, presence: true
|
||||||
validates_length_of :name, :in => 4..60
|
validates :name, length: { in: 4..60 }
|
||||||
validates_length_of :unit, :in => 1..15
|
validates :unit, length: { in: 1..15 }
|
||||||
validates_length_of :note, :maximum => 255
|
validates :note, length: { maximum: 255 }
|
||||||
validates_length_of :origin, :maximum => 255
|
validates :origin, length: { maximum: 255 }
|
||||||
validates_length_of :manufacturer, :maximum => 255
|
validates :manufacturer, length: { maximum: 255 }
|
||||||
validates_length_of :order_number, :maximum => 255
|
validates :order_number, length: { maximum: 255 }
|
||||||
validates_numericality_of :price, :greater_than_or_equal_to => 0
|
validates :price, numericality: { greater_than_or_equal_to: 0 }
|
||||||
validates_numericality_of :unit_quantity, :greater_than => 0
|
validates :unit_quantity, numericality: { greater_than: 0 }
|
||||||
validates_numericality_of :deposit, :tax
|
validates :deposit, :tax, numericality: true
|
||||||
# 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
|
||||||
|
@ -78,12 +78,12 @@ class Article < ApplicationRecord
|
||||||
before_save :update_price_history
|
before_save :update_price_history
|
||||||
before_destroy :check_article_in_use
|
before_destroy :check_article_in_use
|
||||||
|
|
||||||
def self.ransackable_attributes(auth_object = nil)
|
def self.ransackable_attributes(_auth_object = nil)
|
||||||
%w(id name supplier_id article_category_id unit note manufacturer origin unit_quantity order_number)
|
%w[id name supplier_id article_category_id unit note manufacturer origin unit_quantity order_number]
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.ransackable_associations(auth_object = nil)
|
def self.ransackable_associations(_auth_object = nil)
|
||||||
%w(article_category supplier order_articles orders)
|
%w[article_category supplier order_articles orders]
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns true if article has been updated at least 2 days ago
|
# Returns true if article has been updated at least 2 days ago
|
||||||
|
@ -96,7 +96,7 @@ class Article < ApplicationRecord
|
||||||
@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
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -112,15 +112,15 @@ class Article < ApplicationRecord
|
||||||
def shared_article_changed?(supplier = self.supplier)
|
def shared_article_changed?(supplier = self.supplier)
|
||||||
# skip early if the timestamp hasn't changed
|
# skip early if the timestamp hasn't changed
|
||||||
shared_article = self.shared_article(supplier)
|
shared_article = self.shared_article(supplier)
|
||||||
unless shared_article.nil? || self.shared_updated_on == shared_article.updated_on
|
return if shared_article.nil? || shared_updated_on == shared_article.updated_on
|
||||||
attrs = unequal_attributes(shared_article)
|
|
||||||
if attrs.empty?
|
attrs = unequal_attributes(shared_article)
|
||||||
# when attributes not changed, update timestamp of article
|
if attrs.empty?
|
||||||
self.update_attribute(:shared_updated_on, shared_article.updated_on)
|
# when attributes not changed, update timestamp of article
|
||||||
false
|
update_attribute(:shared_updated_on, shared_article.updated_on)
|
||||||
else
|
false
|
||||||
attrs
|
else
|
||||||
end
|
attrs
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -131,30 +131,31 @@ class Article < ApplicationRecord
|
||||||
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 = nil
|
||||||
|
new_unit_quantity = nil
|
||||||
else
|
else
|
||||||
new_price, new_unit_quantity = convert_units(new_article)
|
new_price, new_unit_quantity = convert_units(new_article)
|
||||||
end
|
end
|
||||||
if new_price && new_unit_quantity
|
if new_price && new_unit_quantity
|
||||||
new_unit = self.unit
|
new_unit = unit
|
||||||
else
|
else
|
||||||
new_price = new_article.price
|
new_price = new_article.price
|
||||||
new_unit_quantity = new_article.unit_quantity
|
new_unit_quantity = new_article.unit_quantity
|
||||||
new_unit = new_article.unit
|
new_unit = new_article.unit
|
||||||
end
|
end
|
||||||
|
|
||||||
return Article.compare_attributes(
|
Article.compare_attributes(
|
||||||
{
|
{
|
||||||
:name => [self.name, new_article.name],
|
name: [name, new_article.name],
|
||||||
:manufacturer => [self.manufacturer, new_article.manufacturer.to_s],
|
manufacturer: [manufacturer, new_article.manufacturer.to_s],
|
||||||
:origin => [self.origin, new_article.origin],
|
origin: [origin, new_article.origin],
|
||||||
:unit => [self.unit, new_unit],
|
unit: [unit, new_unit],
|
||||||
:price => [self.price.to_f.round(2), new_price.to_f.round(2)],
|
price: [price.to_f.round(2), new_price.to_f.round(2)],
|
||||||
:tax => [self.tax, new_article.tax],
|
tax: [tax, new_article.tax],
|
||||||
:deposit => [self.deposit.to_f.round(2), new_article.deposit.to_f.round(2)],
|
deposit: [deposit.to_f.round(2), new_article.deposit.to_f.round(2)],
|
||||||
# take care of different num-objects.
|
# take care of different num-objects.
|
||||||
:unit_quantity => [self.unit_quantity.to_s.to_f, new_unit_quantity.to_s.to_f],
|
unit_quantity: [unit_quantity.to_s.to_f, new_unit_quantity.to_s.to_f],
|
||||||
:note => [self.note.to_s, new_article.note.to_s]
|
note: [note.to_s, new_article.note.to_s]
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -165,14 +166,20 @@ class Article < ApplicationRecord
|
||||||
# @param attributes [Hash<Symbol, Array>] Attributes with old and new values
|
# @param attributes [Hash<Symbol, Array>] Attributes with old and new values
|
||||||
# @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 do |_name, values|
|
||||||
Hash[unequal_attributes.to_a.map { |a| [a[0], a[1].last] }]
|
values[0] != values[1] && !(values[0].blank? && values[1].blank?)
|
||||||
|
end
|
||||||
|
unequal_attributes.to_a.map { |a| [a[0], a[1].last] }.to_h
|
||||||
end
|
end
|
||||||
|
|
||||||
# to get the correspondent shared article
|
# to get the correspondent shared article
|
||||||
def shared_article(supplier = self.supplier)
|
def shared_article(supplier = self.supplier)
|
||||||
self.order_number.blank? and return nil
|
order_number.blank? and return nil
|
||||||
@shared_article ||= supplier.shared_supplier.find_article_by_number(self.order_number) rescue nil
|
@shared_article ||= begin
|
||||||
|
supplier.shared_supplier.find_article_by_number(order_number)
|
||||||
|
rescue StandardError
|
||||||
|
nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# convert units in foodcoop-size
|
# convert units in foodcoop-size
|
||||||
|
@ -181,31 +188,37 @@ class Article < ApplicationRecord
|
||||||
# returns false if units aren't foodsoft-compatible
|
# returns false if units aren't foodsoft-compatible
|
||||||
# returns nil if units are eqal
|
# returns nil if units are eqal
|
||||||
def convert_units(new_article = shared_article)
|
def convert_units(new_article = shared_article)
|
||||||
if unit != new_article.unit
|
return unless unit != new_article.unit
|
||||||
# legacy, used by foodcoops in Germany
|
|
||||||
if new_article.unit == "KI" && unit == "ST" # 'KI' means a box, with a different amount of items in it
|
# legacy, used by foodcoops in Germany
|
||||||
# try to match the size out of its name, e.g. "banana 10-12 St" => 10
|
if new_article.unit == 'KI' && unit == 'ST' # 'KI' means a box, with a different amount of items in it
|
||||||
new_unit_quantity = /[0-9\-\s]+(St)/.match(new_article.name).to_s.to_i
|
# try to match the size out of its name, e.g. "banana 10-12 St" => 10
|
||||||
if new_unit_quantity && new_unit_quantity > 0
|
new_unit_quantity = /[0-9\-\s]+(St)/.match(new_article.name).to_s.to_i
|
||||||
new_price = (new_article.price / new_unit_quantity.to_f).round(2)
|
if new_unit_quantity && new_unit_quantity > 0
|
||||||
[new_price, new_unit_quantity]
|
new_price = (new_article.price / new_unit_quantity.to_f).round(2)
|
||||||
else
|
[new_price, new_unit_quantity]
|
||||||
false
|
else
|
||||||
end
|
false
|
||||||
else # use ruby-units to convert
|
end
|
||||||
fc_unit = (::Unit.new(unit) rescue nil)
|
else # use ruby-units to convert
|
||||||
supplier_unit = (::Unit.new(new_article.unit) rescue nil)
|
fc_unit = begin
|
||||||
if fc_unit && supplier_unit && fc_unit =~ supplier_unit
|
::Unit.new(unit)
|
||||||
conversion_factor = (supplier_unit / fc_unit).to_base.to_r
|
rescue StandardError
|
||||||
new_price = new_article.price / conversion_factor
|
nil
|
||||||
new_unit_quantity = new_article.unit_quantity * conversion_factor
|
end
|
||||||
[new_price, new_unit_quantity]
|
supplier_unit = begin
|
||||||
else
|
::Unit.new(new_article.unit)
|
||||||
false
|
rescue StandardError
|
||||||
end
|
nil
|
||||||
|
end
|
||||||
|
if fc_unit && supplier_unit && fc_unit =~ supplier_unit
|
||||||
|
conversion_factor = (supplier_unit / fc_unit).to_base.to_r
|
||||||
|
new_price = new_article.price / conversion_factor
|
||||||
|
new_unit_quantity = new_article.unit_quantity * conversion_factor
|
||||||
|
[new_price, new_unit_quantity]
|
||||||
|
else
|
||||||
|
false
|
||||||
end
|
end
|
||||||
else
|
|
||||||
nil
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -222,19 +235,19 @@ class Article < ApplicationRecord
|
||||||
|
|
||||||
# Checks if the article is in use before it will deleted
|
# Checks if the article is in use before it will deleted
|
||||||
def check_article_in_use
|
def check_article_in_use
|
||||||
raise I18n.t('articles.model.error_in_use', :article => self.name.to_s) if self.in_open_order
|
raise I18n.t('articles.model.error_in_use', article: name.to_s) if in_open_order
|
||||||
end
|
end
|
||||||
|
|
||||||
# Create an ArticlePrice, when the price-attr are changed.
|
# Create an ArticlePrice, when the price-attr are changed.
|
||||||
def update_price_history
|
def update_price_history
|
||||||
if price_changed?
|
return unless price_changed?
|
||||||
article_prices.build(
|
|
||||||
:price => price,
|
article_prices.build(
|
||||||
:tax => tax,
|
price: price,
|
||||||
:deposit => deposit,
|
tax: tax,
|
||||||
:unit_quantity => unit_quantity
|
deposit: deposit,
|
||||||
)
|
unit_quantity: unit_quantity
|
||||||
end
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def price_changed?
|
def price_changed?
|
||||||
|
@ -250,8 +263,8 @@ class Article < ApplicationRecord
|
||||||
# supplier should always be there - except, perhaps, on initialization (on seeding)
|
# supplier should always be there - except, perhaps, on initialization (on seeding)
|
||||||
if supplier && (supplier.shared_sync_method.blank? || supplier.shared_sync_method == 'import')
|
if supplier && (supplier.shared_sync_method.blank? || supplier.shared_sync_method == 'import')
|
||||||
errors.add :name, :taken if matches.any?
|
errors.add :name, :taken if matches.any?
|
||||||
else
|
elsif 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?
|
errors.add :name, :taken_with_unit
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -17,16 +17,16 @@ class ArticleCategory < ApplicationRecord
|
||||||
|
|
||||||
normalize_attributes :name, :description
|
normalize_attributes :name, :description
|
||||||
|
|
||||||
validates :name, :presence => true, :uniqueness => true, :length => { :minimum => 2 }
|
validates :name, presence: true, uniqueness: true, length: { minimum: 2 }
|
||||||
|
|
||||||
before_destroy :check_for_associated_articles
|
before_destroy :check_for_associated_articles
|
||||||
|
|
||||||
def self.ransackable_attributes(auth_object = nil)
|
def self.ransackable_attributes(_auth_object = nil)
|
||||||
%w(id name)
|
%w[id name]
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.ransackable_associations(auth_object = nil)
|
def self.ransackable_associations(_auth_object = nil)
|
||||||
%w(articles order_articles orders)
|
%w[articles order_articles orders]
|
||||||
end
|
end
|
||||||
|
|
||||||
# Find a category that matches a category name; may return nil.
|
# Find a category that matches a category name; may return nil.
|
||||||
|
@ -40,7 +40,11 @@ class ArticleCategory < ApplicationRecord
|
||||||
# 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?
|
unless c && c.any?
|
||||||
|
c = ArticleCategory.where('description LIKE ?', "%#{category}%").select do |s|
|
||||||
|
s.description.match(/(^|,)\s*#{category}\s*(,|$)/i)
|
||||||
|
end
|
||||||
|
end
|
||||||
# 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
|
||||||
|
@ -50,6 +54,9 @@ class ArticleCategory < ApplicationRecord
|
||||||
|
|
||||||
# Deny deleting the category when there are associated articles.
|
# Deny deleting the category when there are associated articles.
|
||||||
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?
|
return unless articles.undeleted.exists?
|
||||||
|
|
||||||
|
raise I18n.t('activerecord.errors.has_many_left',
|
||||||
|
collection: Article.model_name.human)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -24,8 +24,8 @@ class ArticlePrice < ApplicationRecord
|
||||||
|
|
||||||
localize_input_of :price, :tax, :deposit
|
localize_input_of :price, :tax, :deposit
|
||||||
|
|
||||||
validates_presence_of :price, :tax, :deposit, :unit_quantity
|
validates :price, :tax, :deposit, :unit_quantity, presence: true
|
||||||
validates_numericality_of :price, :greater_than_or_equal_to => 0
|
validates :price, numericality: { greater_than_or_equal_to: 0 }
|
||||||
validates_numericality_of :unit_quantity, :greater_than => 0
|
validates :unit_quantity, numericality: { greater_than: 0 }
|
||||||
validates_numericality_of :deposit, :tax
|
validates :deposit, :tax, numericality: true
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,10 +5,10 @@ class BankAccount < ApplicationRecord
|
||||||
|
|
||||||
normalize_attributes :name, :iban, :description
|
normalize_attributes :name, :iban, :description
|
||||||
|
|
||||||
validates :name, :presence => true, :uniqueness => true, :length => { :minimum => 2 }
|
validates :name, presence: true, uniqueness: true, length: { minimum: 2 }
|
||||||
validates :iban, :presence => true, :uniqueness => true
|
validates :iban, presence: true, uniqueness: true
|
||||||
validates_format_of :iban, :with => /\A[A-Z]{2}[0-9]{2}[0-9A-Z]{,30}\z/
|
validates :iban, format: { with: /\A[A-Z]{2}[0-9]{2}[0-9A-Z]{,30}\z/ }
|
||||||
validates_numericality_of :balance, :message => I18n.t('bank_account.model.invalid_balance')
|
validates :balance, numericality: { message: I18n.t('bank_account.model.invalid_balance') }
|
||||||
|
|
||||||
# @return [Function] Method wich can be called to import transaction from a bank or nil if unsupported
|
# @return [Function] Method wich can be called to import transaction from a bank or nil if unsupported
|
||||||
def find_connector
|
def find_connector
|
||||||
|
@ -18,10 +18,8 @@ class BankAccount < ApplicationRecord
|
||||||
|
|
||||||
def assign_unlinked_transactions
|
def assign_unlinked_transactions
|
||||||
count = 0
|
count = 0
|
||||||
bank_transactions.without_financial_link.includes(:supplier, :user).each do |t|
|
bank_transactions.without_financial_link.includes(:supplier, :user).find_each do |t|
|
||||||
if t.assign_to_ordergroup || t.assign_to_invoice
|
count += 1 if t.assign_to_ordergroup || t.assign_to_invoice
|
||||||
count += 1
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
count
|
count
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,5 +4,5 @@ class BankGateway < ApplicationRecord
|
||||||
|
|
||||||
scope :with_unattended_support, -> { where.not(unattended_user: nil) }
|
scope :with_unattended_support, -> { where.not(unattended_user: nil) }
|
||||||
|
|
||||||
validates_presence_of :name, :url
|
validates :name, :url, presence: true
|
||||||
end
|
end
|
||||||
|
|
|
@ -22,8 +22,8 @@ class BankTransaction < ApplicationRecord
|
||||||
belongs_to :supplier, optional: true, foreign_key: 'iban', primary_key: 'iban'
|
belongs_to :supplier, optional: true, foreign_key: 'iban', primary_key: 'iban'
|
||||||
belongs_to :user, optional: true, foreign_key: 'iban', primary_key: 'iban'
|
belongs_to :user, optional: true, foreign_key: 'iban', primary_key: 'iban'
|
||||||
|
|
||||||
validates_presence_of :date, :amount, :bank_account_id
|
validates :date, :amount, :bank_account_id, presence: true
|
||||||
validates_numericality_of :amount
|
validates :amount, numericality: true
|
||||||
|
|
||||||
scope :without_financial_link, -> { where(financial_link: nil) }
|
scope :without_financial_link, -> { where(financial_link: nil) }
|
||||||
|
|
||||||
|
@ -31,13 +31,13 @@ class BankTransaction < ApplicationRecord
|
||||||
localize_input_of :amount
|
localize_input_of :amount
|
||||||
|
|
||||||
def image_url
|
def image_url
|
||||||
'data:image/png;base64,' + Base64.encode64(self.image)
|
'data:image/png;base64,' + Base64.encode64(image)
|
||||||
end
|
end
|
||||||
|
|
||||||
def assign_to_invoice
|
def assign_to_invoice
|
||||||
return false unless supplier
|
return false unless supplier
|
||||||
|
|
||||||
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
|
||||||
|
@ -49,7 +49,7 @@ class BankTransaction < ApplicationRecord
|
||||||
update_attribute :financial_link, link
|
update_attribute :financial_link, link
|
||||||
end
|
end
|
||||||
|
|
||||||
return true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
def assign_to_ordergroup
|
def assign_to_ordergroup
|
||||||
|
@ -78,6 +78,6 @@ class BankTransaction < ApplicationRecord
|
||||||
update_attribute :financial_link, link
|
update_attribute :financial_link, link
|
||||||
end
|
end
|
||||||
|
|
||||||
return true
|
true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,7 +10,7 @@ module CustomFields
|
||||||
end
|
end
|
||||||
|
|
||||||
after_save do
|
after_save do
|
||||||
self.settings.custom_fields = custom_fields if custom_fields
|
settings.custom_fields = custom_fields if custom_fields
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,9 +3,9 @@ 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 = {}, &block)
|
||||||
find_in_batches_with_order(options) do |records|
|
find_in_batches_with_order(options) do |records|
|
||||||
records.each { |record| yield record }
|
records.each(&block)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -5,12 +5,12 @@ module LocalizeInput
|
||||||
return input unless input.is_a? String
|
return input unless input.is_a? String
|
||||||
|
|
||||||
Rails.logger.debug { "Input: #{input.inspect}" }
|
Rails.logger.debug { "Input: #{input.inspect}" }
|
||||||
separator = I18n.t("separator", scope: "number.format")
|
separator = I18n.t('separator', scope: 'number.format')
|
||||||
delimiter = I18n.t("delimiter", scope: "number.format")
|
delimiter = I18n.t('delimiter', scope: 'number.format')
|
||||||
input.gsub!(delimiter, "") if input.match(/\d+#{Regexp.escape(delimiter)}+\d+#{Regexp.escape(separator)}+\d+/) # Remove delimiter
|
input.gsub!(delimiter, '') if input.match(/\d+#{Regexp.escape(delimiter)}+\d+#{Regexp.escape(separator)}+\d+/) # Remove delimiter
|
||||||
input.gsub!(separator, ".") # Replace separator with db compatible character
|
input.gsub!(separator, '.') # Replace separator with db compatible character
|
||||||
input
|
input
|
||||||
rescue
|
rescue StandardError
|
||||||
Rails.logger.warn "Can't localize input: #{input}"
|
Rails.logger.warn "Can't localize input: #{input}"
|
||||||
input
|
input
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,7 +3,7 @@ module MarkAsDeletedWithName
|
||||||
|
|
||||||
def mark_as_deleted
|
def mark_as_deleted
|
||||||
# get maximum length of name
|
# get maximum length of name
|
||||||
max_length = 100000
|
max_length = 100_000
|
||||||
if lenval = self.class.validators_on(:name).detect { |v| v.is_a?(ActiveModel::Validations::LengthValidator) }
|
if lenval = self.class.validators_on(:name).detect { |v| v.is_a?(ActiveModel::Validations::LengthValidator) }
|
||||||
max_length = lenval.options[:maximum]
|
max_length = lenval.options[:maximum]
|
||||||
end
|
end
|
||||||
|
|
|
@ -15,6 +15,6 @@ module PriceCalculation
|
||||||
private
|
private
|
||||||
|
|
||||||
def add_percent(value, percent)
|
def add_percent(value, percent)
|
||||||
(value * (percent * 0.01 + 1)).round(2)
|
(value * ((percent * 0.01) + 1)).round(2)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,10 +4,10 @@ class Delivery < StockEvent
|
||||||
|
|
||||||
scope :recent, -> { order('created_at DESC').limit(10) }
|
scope :recent, -> { order('created_at DESC').limit(10) }
|
||||||
|
|
||||||
validates_presence_of :supplier_id
|
validates :supplier_id, presence: true
|
||||||
validate :stock_articles_must_be_unique
|
validate :stock_articles_must_be_unique
|
||||||
|
|
||||||
accepts_nested_attributes_for :stock_changes, :allow_destroy => :true
|
accepts_nested_attributes_for :stock_changes, allow_destroy: :true
|
||||||
|
|
||||||
def new_stock_changes=(stock_change_attributes)
|
def new_stock_changes=(stock_change_attributes)
|
||||||
for attributes in stock_change_attributes
|
for attributes in stock_change_attributes
|
||||||
|
@ -16,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
|
stock_changes.map { |stock_change| stock_change.stock_article.id }.include? article.id
|
||||||
end
|
end
|
||||||
|
|
||||||
def sum(type = :gross)
|
def sum(type = :gross)
|
||||||
|
@ -39,8 +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?
|
return if 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'))
|
|
||||||
end
|
errors.add(:base, I18n.t('model.delivery.each_stock_article_must_be_unique'))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,13 +4,13 @@ class FinancialLink < ApplicationRecord
|
||||||
has_many :invoices
|
has_many :invoices
|
||||||
|
|
||||||
scope :incomplete, -> { with_full_sum.where.not('full_sums.full_sum' => 0) }
|
scope :incomplete, -> { with_full_sum.where.not('full_sums.full_sum' => 0) }
|
||||||
scope :unused, -> {
|
scope :unused, lambda {
|
||||||
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, lambda {
|
||||||
select(:id, :note, :full_sum).joins(<<-SQL)
|
select(:id, :note, :full_sum).joins(<<-SQL)
|
||||||
LEFT JOIN (
|
LEFT JOIN (
|
||||||
SELECT id, COALESCE(bt_sum, 0) - COALESCE(ft_sum, 0) + COALESCE(i_sum, 0) AS full_sum
|
SELECT id, COALESCE(bt_sum, 0) - COALESCE(ft_sum, 0) + COALESCE(i_sum, 0) AS full_sum
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue