12_generate_custom_csv_file #58
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
|
||||
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 'rails', '~> 7.0'
|
||||
|
||||
|
||||
gem 'sassc-rails'
|
||||
gem 'less-rails'
|
||||
gem 'sassc-rails'
|
||||
gem 'uglifier'
|
||||
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
|
||||
gem 'therubyracer', platforms: :ruby
|
||||
|
||||
gem 'jquery-rails'
|
||||
gem 'select2-rails'
|
||||
gem 'rails_tokeninput'
|
||||
gem 'bootsnap', require: false
|
||||
gem 'bootstrap-datepicker-rails'
|
||||
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 '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 'bootsnap', require: false
|
||||
gem 'rails_tokeninput'
|
||||
gem 'select2-rails'
|
||||
|
||||
gem 'mysql2'
|
||||
gem 'prawn'
|
||||
gem 'prawn-table'
|
||||
gem 'haml'
|
||||
gem 'haml-rails'
|
||||
gem 'kaminari'
|
||||
gem 'simple_form'
|
||||
gem 'inherited_resources'
|
||||
gem 'active_model_serializers', '~> 0.10.0'
|
||||
gem 'acts_as_tree'
|
||||
gem 'attribute_normalizer'
|
||||
gem 'daemons'
|
||||
gem 'doorkeeper'
|
||||
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 'active_model_serializers', '~> 0.10.0'
|
||||
gem 'twitter-bootstrap-rails', '~> 2.2.8'
|
||||
gem 'rails-settings-cached', '= 0.4.3' # caching breaks tests until Rails 5 https://github.com/huacnlee/rails-settings-cached/issues/73
|
||||
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-bootstrap'
|
||||
gem 'sprockets', '< 4'
|
||||
gem 'ransack'
|
||||
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 'twitter-bootstrap-rails', '~> 2.2.8'
|
||||
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
|
||||
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 'roo'
|
||||
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-ui'
|
||||
gem 'ruby-filemagic'
|
||||
gem 'spreadsheet'
|
||||
|
||||
# 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 '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_documents', path: 'plugins/documents'
|
||||
gem 'foodsoft_links', path: 'plugins/links'
|
||||
gem 'foodsoft_messages', path: 'plugins/messages'
|
||||
gem 'foodsoft_polls', path: 'plugins/polls'
|
||||
gem 'foodsoft_wiki', path: 'plugins/wiki'
|
||||
|
||||
# plugins not enabled by default
|
||||
# gem 'foodsoft_current_orders', path: 'plugins/current_orders'
|
||||
|
@ -77,10 +76,10 @@ gem 'foodsoft_polls', path: 'plugins/polls'
|
|||
# gem 'foodsoft_uservoice', path: 'plugins/uservoice'
|
||||
|
||||
group :development do
|
||||
gem 'sqlite3', '~> 1.3.6'
|
||||
gem 'mailcatcher'
|
||||
gem 'web-console'
|
||||
gem 'listen'
|
||||
gem 'mailcatcher'
|
||||
gem 'sqlite3', '~> 1.3.6'
|
||||
gem 'web-console'
|
||||
|
||||
# Better error output
|
||||
gem 'better_errors'
|
||||
|
@ -108,17 +107,17 @@ group :development, :test do
|
|||
end
|
||||
|
||||
group :test do
|
||||
gem 'rspec-rails'
|
||||
gem 'apparition' # Capybara javascript driver
|
||||
gem 'capybara'
|
||||
gem 'connection_pool'
|
||||
gem 'database_cleaner'
|
||||
gem 'factory_bot_rails'
|
||||
gem 'faker'
|
||||
gem 'capybara'
|
||||
gem 'apparition' # Capybara javascript driver
|
||||
gem 'database_cleaner'
|
||||
gem 'connection_pool'
|
||||
gem 'rspec-rails'
|
||||
# need to include rspec components before i18n-spec or rake fails in test environment
|
||||
gem 'i18n-spec'
|
||||
gem 'rspec-core'
|
||||
gem 'rspec-rerun'
|
||||
gem 'i18n-spec'
|
||||
# code coverage
|
||||
gem 'simplecov', require: false
|
||||
gem 'simplecov-lcov', require: false
|
||||
|
|
2
Rakefile
2
Rakefile
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env 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 'rspec-rerun/tasks' if defined?(RSpec) # http://stackoverflow.com/a/16853615/2866660
|
||||
|
||||
|
|
|
@ -3,39 +3,39 @@ class Admin::BankAccountsController < Admin::BaseController
|
|||
|
||||
def new
|
||||
@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
|
||||
|
||||
def create
|
||||
@bank_account = BankAccount.new(params[:bank_account])
|
||||
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
|
||||
render :action => 'new', :layout => false
|
||||
render action: 'new', layout: false
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
@bank_account = BankAccount.find(params[:id])
|
||||
render :action => 'new', :layout => false
|
||||
end
|
||||
|
||||
def update
|
||||
@bank_account = BankAccount.find(params[:id])
|
||||
|
||||
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
|
||||
render :action => 'new', :layout => false
|
||||
render action: 'new', layout: false
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@bank_account = BankAccount.find(params[:id])
|
||||
@bank_account.destroy
|
||||
redirect_to update_bank_accounts_admin_finances_url, :status => 303
|
||||
rescue => error
|
||||
flash.now[:alert] = error.message
|
||||
redirect_to update_bank_accounts_admin_finances_url, status: :see_other
|
||||
rescue StandardError => e
|
||||
flash.now[:alert] = e.message
|
||||
render template: 'shared/alert'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,6 +6,11 @@ class Admin::BankGatewaysController < Admin::BaseController
|
|||
render layout: false
|
||||
end
|
||||
|
||||
def edit
|
||||
@bank_gateway = BankGateway.find(params[:id])
|
||||
render action: 'new', layout: false
|
||||
end
|
||||
|
||||
def create
|
||||
@bank_gateway = BankGateway.new(params[:bank_gateway])
|
||||
if @bank_gateway.valid? && @bank_gateway.save
|
||||
|
@ -15,11 +20,6 @@ class Admin::BankGatewaysController < Admin::BaseController
|
|||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
@bank_gateway = BankGateway.find(params[:id])
|
||||
render action: 'new', layout: false
|
||||
end
|
||||
|
||||
def update
|
||||
@bank_gateway = BankGateway.find(params[:id])
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
class Admin::ConfigsController < Admin::BaseController
|
||||
before_action :get_tabs, only: [:show, :list]
|
||||
before_action :get_tabs, only: %i[show list]
|
||||
|
||||
def show
|
||||
@current_tab = @tabs.include?(params[:tab]) ? params[:tab] : @tabs.first
|
||||
|
@ -16,7 +16,7 @@ class Admin::ConfigsController < Admin::BaseController
|
|||
def update
|
||||
parse_recurring_selects! params[:config][:order_schedule]
|
||||
ActiveRecord::Base.transaction do
|
||||
# TODO support nested configuration keys
|
||||
# TODO: support nested configuration keys
|
||||
params[:config].each do |key, val|
|
||||
FoodsoftConfig[key] = convert_config_value val
|
||||
end
|
||||
|
@ -29,7 +29,7 @@ class Admin::ConfigsController < Admin::BaseController
|
|||
|
||||
# Set configuration tab names as `@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
|
||||
engines = Rails::Engine.subclasses.map(&:instance).select { |e| e.respond_to?(:configuration) }
|
||||
engines.each { |e| e.configuration(@tabs, self) }
|
||||
|
@ -38,8 +38,9 @@ class Admin::ConfigsController < Admin::BaseController
|
|||
|
||||
# turn recurring rules into something palatable
|
||||
def parse_recurring_selects!(config)
|
||||
if config
|
||||
for k in [:pickup, :boxfill, :ends] do
|
||||
return unless config
|
||||
|
||||
for k in %i[pickup boxfill ends] do
|
||||
if config[k]
|
||||
# allow clearing it using dummy value '{}' ('' would break recurring_select)
|
||||
if config[k][:recurr].present? && config[k][:recurr] != '{}'
|
||||
|
@ -51,7 +52,6 @@ class Admin::ConfigsController < Admin::BaseController
|
|||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def convert_config_value(value)
|
||||
if value.is_a? ActionController::Parameters
|
||||
|
|
|
@ -10,21 +10,21 @@ class Admin::FinancesController < Admin::BaseController
|
|||
|
||||
def update_bank_accounts
|
||||
@bank_accounts = BankAccount.order('name')
|
||||
render :layout => false
|
||||
render layout: false
|
||||
end
|
||||
|
||||
def update_bank_gateways
|
||||
@bank_gateways = BankGateway.order('name')
|
||||
render :layout => false
|
||||
render layout: false
|
||||
end
|
||||
|
||||
def update_transaction_types
|
||||
@financial_transaction_classes = FinancialTransactionClass.includes(:financial_transaction_types).order('name ASC')
|
||||
render :layout => false
|
||||
render layout: false
|
||||
end
|
||||
|
||||
def update_supplier_categories
|
||||
@supplier_categories = SupplierCategory.order('name')
|
||||
render :layout => false
|
||||
render layout: false
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,25 +6,25 @@ class Admin::FinancialTransactionClassesController < Admin::BaseController
|
|||
render layout: false
|
||||
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
|
||||
@financial_transaction_class = FinancialTransactionClass.find(params[:id])
|
||||
render action: 'new', layout: false
|
||||
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
|
||||
@financial_transaction_class = FinancialTransactionClass.find(params[:id])
|
||||
|
||||
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
|
||||
render action: 'new', layout: false
|
||||
end
|
||||
|
@ -33,9 +33,9 @@ class Admin::FinancialTransactionClassesController < Admin::BaseController
|
|||
def destroy
|
||||
@financial_transaction_class = FinancialTransactionClass.find(params[:id])
|
||||
@financial_transaction_class.destroy!
|
||||
redirect_to update_transaction_types_admin_finances_url, status: 303
|
||||
rescue => error
|
||||
flash.now[:alert] = error.message
|
||||
redirect_to update_transaction_types_admin_finances_url, status: :see_other
|
||||
rescue StandardError => e
|
||||
flash.now[:alert] = e.message
|
||||
render template: 'shared/alert'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,25 +7,25 @@ class Admin::FinancialTransactionTypesController < Admin::BaseController
|
|||
render layout: false
|
||||
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
|
||||
@financial_transaction_type = FinancialTransactionType.find(params[:id])
|
||||
render action: 'new', layout: false
|
||||
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
|
||||
@financial_transaction_type = FinancialTransactionType.find(params[:id])
|
||||
|
||||
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
|
||||
render action: 'new', layout: false
|
||||
end
|
||||
|
@ -34,9 +34,9 @@ class Admin::FinancialTransactionTypesController < Admin::BaseController
|
|||
def destroy
|
||||
@financial_transaction_type = FinancialTransactionType.find(params[:id])
|
||||
@financial_transaction_type.destroy!
|
||||
redirect_to update_transaction_types_admin_finances_url, status: 303
|
||||
rescue => error
|
||||
flash.now[:alert] = error.message
|
||||
redirect_to update_transaction_types_admin_finances_url, status: :see_other
|
||||
rescue StandardError => e
|
||||
flash.now[:alert] = e.message
|
||||
render template: 'shared/alert'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,28 +3,28 @@ class Admin::MailDeliveryStatusController < Admin::BaseController
|
|||
|
||||
def index
|
||||
@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)
|
||||
end
|
||||
|
||||
def show
|
||||
@maildeliverystatus = MailDeliveryStatus.find(params[:id])
|
||||
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
|
||||
|
||||
def destroy_all
|
||||
@maildeliverystatus = MailDeliveryStatus.delete_all
|
||||
redirect_to admin_mail_delivery_status_index_path, notice: t('.notice')
|
||||
rescue => error
|
||||
redirect_to admin_mail_delivery_status_index_path, alert: I18n.t('errors.general_msg', msg: error.message)
|
||||
rescue StandardError => e
|
||||
redirect_to admin_mail_delivery_status_index_path, alert: I18n.t('errors.general_msg', msg: e.message)
|
||||
end
|
||||
|
||||
def destroy
|
||||
@maildeliverystatus = MailDeliveryStatus.find(params[:id])
|
||||
@maildeliverystatus.destroy
|
||||
redirect_to admin_mail_delivery_status_index_path, notice: t('.notice')
|
||||
rescue => error
|
||||
redirect_to admin_mail_delivery_status_index_path, alert: I18n.t('errors.general_msg', msg: error.message)
|
||||
rescue StandardError => e
|
||||
redirect_to admin_mail_delivery_status_index_path, alert: I18n.t('errors.general_msg', msg: e.message)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,16 +2,15 @@ class Admin::OrdergroupsController < Admin::BaseController
|
|||
inherit_resources
|
||||
|
||||
def index
|
||||
@ordergroups = Ordergroup.undeleted.sort_by_param(params["sort"])
|
||||
@ordergroups = Ordergroup.undeleted.sort_by_param(params['sort'])
|
||||
|
||||
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
|
||||
|
||||
# if somebody uses the search field:
|
||||
unless params[:query].blank?
|
||||
@ordergroups = @ordergroups.where('name LIKE ?', "%#{params[:query]}%")
|
||||
end
|
||||
@ordergroups = @ordergroups.where('name LIKE ?', "%#{params[:query]}%") if params[:query].present?
|
||||
|
||||
@ordergroups = @ordergroups.page(params[:page]).per(@per_page)
|
||||
end
|
||||
|
@ -19,8 +18,8 @@ class Admin::OrdergroupsController < Admin::BaseController
|
|||
def destroy
|
||||
@ordergroup = Ordergroup.find(params[:id])
|
||||
@ordergroup.mark_as_deleted
|
||||
redirect_to admin_ordergroups_url, notice: t('admin.ordergroups.destroy.notice')
|
||||
rescue => error
|
||||
redirect_to admin_ordergroups_url, alert: t('admin.ordergroups.destroy.error')
|
||||
redirect_to admin_ordergroups_url, notice: t('.notice')
|
||||
rescue StandardError => e
|
||||
redirect_to admin_ordergroups_url, alert: t('.error')
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,6 +6,11 @@ class Admin::SupplierCategoriesController < Admin::BaseController
|
|||
render layout: false
|
||||
end
|
||||
|
||||
def edit
|
||||
@supplier_category = SupplierCategory.find(params[:id])
|
||||
render action: 'new', layout: false
|
||||
end
|
||||
|
||||
def create
|
||||
@supplier_category = SupplierCategory.new(params[:supplier_category])
|
||||
if @supplier_category.valid? && @supplier_category.save
|
||||
|
@ -15,11 +20,6 @@ class Admin::SupplierCategoriesController < Admin::BaseController
|
|||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
@supplier_category = SupplierCategory.find(params[:id])
|
||||
render action: 'new', layout: false
|
||||
end
|
||||
|
||||
def update
|
||||
@supplier_category = SupplierCategory.find(params[:id])
|
||||
|
||||
|
|
|
@ -3,16 +3,14 @@ class Admin::UsersController < Admin::BaseController
|
|||
|
||||
def index
|
||||
@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)
|
||||
|
||||
if request.format.csv?
|
||||
send_data UsersCsv.new(@users).to_csv, filename: 'users.csv', type: 'text/csv'
|
||||
end
|
||||
send_data UsersCsv.new(@users).to_csv, filename: 'users.csv', type: 'text/csv' if request.format.csv?
|
||||
|
||||
# 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)
|
||||
end
|
||||
|
@ -20,17 +18,17 @@ class Admin::UsersController < Admin::BaseController
|
|||
def destroy
|
||||
@user = User.find(params[:id])
|
||||
@user.mark_as_deleted
|
||||
redirect_to admin_users_url, notice: t('admin.users.destroy.notice')
|
||||
rescue => error
|
||||
redirect_to admin_users_url, alert: t('admin.users.destroy.error', error: error.message)
|
||||
redirect_to admin_users_url, notice: t('.notice')
|
||||
rescue StandardError => e
|
||||
redirect_to admin_users_url, alert: t('.error', error: e.message)
|
||||
end
|
||||
|
||||
def restore
|
||||
@user = User.find(params[:id])
|
||||
@user.restore
|
||||
redirect_to admin_users_url, notice: t('admin.users.restore.notice')
|
||||
rescue => error
|
||||
redirect_to admin_users_url, alert: t('admin.users.restore.error', error: error.message)
|
||||
redirect_to admin_users_url, notice: t('.notice')
|
||||
rescue StandardError => e
|
||||
redirect_to admin_users_url, alert: t('.error', error: e.message)
|
||||
end
|
||||
|
||||
def sudo
|
||||
|
|
|
@ -4,7 +4,7 @@ class Admin::WorkgroupsController < Admin::BaseController
|
|||
def index
|
||||
@workgroups = Workgroup.order('name ASC')
|
||||
# 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)
|
||||
end
|
||||
|
@ -12,8 +12,8 @@ class Admin::WorkgroupsController < Admin::BaseController
|
|||
def destroy
|
||||
@workgroup = Workgroup.find(params[:id])
|
||||
@workgroup.destroy
|
||||
redirect_to admin_workgroups_url, notice: t('admin.workgroups.destroy.notice')
|
||||
rescue => error
|
||||
redirect_to admin_workgroups_url, alert: t('admin.workgroups.destroy.error', error: error.message)
|
||||
redirect_to admin_workgroups_url, notice: t('.notice')
|
||||
rescue StandardError => e
|
||||
redirect_to admin_workgroups_url, alert: t('.error', error: e.message)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -20,29 +20,30 @@ class Api::V1::BaseController < ApplicationController
|
|||
|
||||
def require_ordergroup
|
||||
authenticate
|
||||
unless current_ordergroup.present?
|
||||
raise Api::Errors::PermissionRequired.new('Forbidden, must be in an ordergroup')
|
||||
end
|
||||
return if current_ordergroup.present?
|
||||
|
||||
raise Api::Errors::PermissionRequired, 'Forbidden, must be in an ordergroup'
|
||||
end
|
||||
|
||||
def require_minimum_balance
|
||||
minimum_balance = FoodsoftConfig[:minimum_balance] or return
|
||||
if current_ordergroup.account_balance < minimum_balance
|
||||
raise Api::Errors::PermissionRequired.new(t('application.controller.error_minimum_balance', min: minimum_balance))
|
||||
end
|
||||
return unless current_ordergroup.account_balance < minimum_balance
|
||||
|
||||
raise Api::Errors::PermissionRequired, t('application.controller.error_minimum_balance', min: minimum_balance)
|
||||
end
|
||||
|
||||
def require_enough_apples
|
||||
if 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)
|
||||
end
|
||||
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, s
|
||||
end
|
||||
|
||||
def require_config_enabled(config)
|
||||
unless FoodsoftConfig[config]
|
||||
raise Api::Errors::PermissionRequired.new(t('application.controller.error_not_enabled', config: config))
|
||||
end
|
||||
return if FoodsoftConfig[config]
|
||||
|
||||
raise Api::Errors::PermissionRequired, t('application.controller.error_not_enabled', config: config)
|
||||
end
|
||||
|
||||
def skip_session
|
||||
|
@ -52,12 +53,12 @@ class Api::V1::BaseController < ApplicationController
|
|||
def not_found_handler(e)
|
||||
# remove where-clauses from error message (not suitable for end-users)
|
||||
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
|
||||
|
||||
def not_acceptable_handler(e)
|
||||
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
|
||||
|
||||
def doorkeeper_unauthorized_render_options(error:)
|
||||
|
@ -70,11 +71,11 @@ class Api::V1::BaseController < ApplicationController
|
|||
|
||||
def permission_required_handler(e)
|
||||
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
|
||||
|
||||
# @todo something with ApplicationHelper#show_user
|
||||
def show_user(user = current_user, **options)
|
||||
def show_user(user = current_user, **_options)
|
||||
user.display
|
||||
end
|
||||
end
|
||||
|
|
|
@ -16,7 +16,8 @@ class Api::V1::User::FinancialTransactionsController < Api::V1::BaseController
|
|||
|
||||
def create
|
||||
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
|
||||
end
|
||||
|
||||
|
|
|
@ -4,8 +4,8 @@ class Api::V1::User::GroupOrderArticlesController < Api::V1::BaseController
|
|||
before_action -> { doorkeeper_authorize! 'group_orders:user' }
|
||||
|
||||
before_action :require_ordergroup
|
||||
before_action :require_minimum_balance, only: [:create, :update] # destroy is ok
|
||||
before_action :require_enough_apples, only: [:create, :update] # destroy is ok
|
||||
before_action :require_minimum_balance, only: %i[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
|
||||
|
||||
def index
|
||||
|
@ -35,7 +35,8 @@ class Api::V1::User::GroupOrderArticlesController < Api::V1::BaseController
|
|||
goa = nil
|
||||
GroupOrderArticle.transaction do
|
||||
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.group_order.update_price!
|
||||
goa.group_order.update!(updated_by: current_user)
|
||||
|
|
|
@ -8,13 +8,13 @@ class Api::V1::User::OrdergroupController < Api::V1::BaseController
|
|||
financial_overview: {
|
||||
account_balance: ordergroup.account_balance.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,
|
||||
name: c.display,
|
||||
amount: ordergroup["sum_of_class_#{c.id}"].to_f
|
||||
}
|
||||
}
|
||||
end
|
||||
}
|
||||
}
|
||||
end
|
||||
|
|
|
@ -19,11 +19,11 @@ class ApplicationController < ActionController::Base
|
|||
private
|
||||
|
||||
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
|
||||
end
|
||||
end
|
||||
|
||||
# Many plugins can be turned on and off on the fly with a `use_` configuration option.
|
||||
# To disable a controller in the plugin, you can use this as a `before_action`:
|
||||
|
@ -64,10 +64,10 @@ class ApplicationController < ActionController::Base
|
|||
end
|
||||
|
||||
def items_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
|
||||
@per_page = if params[:per_page] && params[:per_page].to_i > 0 && params[:per_page].to_i <= 500
|
||||
params[:per_page].to_i
|
||||
else
|
||||
@per_page = 20
|
||||
20
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -4,17 +4,17 @@ class ArticleCategoriesController < ApplicationController
|
|||
before_action :authenticate_article_meta
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
def destroy
|
||||
destroy!
|
||||
rescue => error
|
||||
redirect_to article_categories_path, alert: I18n.t('article_categories.destroy.error', message: error.message)
|
||||
rescue StandardError => e
|
||||
redirect_to article_categories_path, alert: I18n.t('article_categories.destroy.error', message: e.message)
|
||||
end
|
||||
|
||||
protected
|
||||
|
|
|
@ -2,24 +2,24 @@ class ArticlesController < ApplicationController
|
|||
before_action :authenticate_article_meta, :find_supplier
|
||||
|
||||
def index
|
||||
if params['sort']
|
||||
sort = case params['sort']
|
||||
when "name" then "articles.name"
|
||||
when "unit" then "articles.unit"
|
||||
when "article_category" then "article_categories.name"
|
||||
when "note" then "articles.note"
|
||||
when "availability" then "articles.availability"
|
||||
when "name_reverse" then "articles.name DESC"
|
||||
when "unit_reverse" then "articles.unit DESC"
|
||||
when "article_category_reverse" then "article_categories.name DESC"
|
||||
when "note_reverse" then "articles.note DESC"
|
||||
when "availability_reverse" then "articles.availability DESC"
|
||||
sort = if params['sort']
|
||||
case params['sort']
|
||||
when 'name' then 'articles.name'
|
||||
when 'unit' then 'articles.unit'
|
||||
when 'article_category' then 'article_categories.name'
|
||||
when 'note' then 'articles.note'
|
||||
when 'availability' then 'articles.availability'
|
||||
when 'name_reverse' then 'articles.name DESC'
|
||||
when 'unit_reverse' then 'articles.unit DESC'
|
||||
when 'article_category_reverse' then 'article_categories.name DESC'
|
||||
when 'note_reverse' then 'articles.note DESC'
|
||||
when 'availability_reverse' then 'articles.availability DESC'
|
||||
end
|
||||
else
|
||||
sort = "article_categories.name, articles.name"
|
||||
'article_categories.name, articles.name'
|
||||
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?
|
||||
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|
|
||||
format.html
|
||||
format.js { render :layout => false }
|
||||
format.js { render layout: false }
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
@article = @supplier.articles.build(:tax => FoodsoftConfig[:tax_default])
|
||||
render :layout => false
|
||||
@article = @supplier.articles.build(tax: FoodsoftConfig[:tax_default])
|
||||
render layout: false
|
||||
end
|
||||
|
||||
def copy
|
||||
@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
|
||||
|
||||
def create
|
||||
@article = Article.new(params[:article])
|
||||
if @article.valid? && @article.save
|
||||
render :layout => false
|
||||
render layout: false
|
||||
else
|
||||
render :action => 'new', :layout => false
|
||||
render action: 'new', layout: false
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
@article = Article.find(params[:id])
|
||||
render :action => 'new', :layout => false
|
||||
end
|
||||
|
||||
# Updates one Article and highlights the line if succeded
|
||||
def update
|
||||
@article = Article.find(params[:id])
|
||||
|
||||
if @article.update(params[:article])
|
||||
render :layout => false
|
||||
render layout: false
|
||||
else
|
||||
render :action => 'new', :layout => false
|
||||
render action: 'new', layout: false
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -75,7 +75,7 @@ class ArticlesController < ApplicationController
|
|||
def destroy
|
||||
@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
|
||||
render :layout => false
|
||||
render layout: false
|
||||
end
|
||||
|
||||
# Renders a form for editing all articles from a supplier
|
||||
|
@ -87,21 +87,19 @@ class ArticlesController < ApplicationController
|
|||
def update_all
|
||||
invalid_articles = false
|
||||
|
||||
begin
|
||||
Article.transaction do
|
||||
unless params[:articles].blank?
|
||||
if params[:articles].present?
|
||||
# Update other article attributes...
|
||||
@articles = Article.find(params[:articles].keys)
|
||||
@articles.each do |article|
|
||||
unless article.update(params[:articles][article.id.to_s])
|
||||
invalid_articles = true unless invalid_articles # Remember that there are validation errors
|
||||
invalid_articles ||= true # Remember that there are validation errors
|
||||
end
|
||||
end
|
||||
|
||||
raise ActiveRecord::Rollback if invalid_articles # Rollback all changes
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if invalid_articles
|
||||
# An error has occurred, transaction has been rolled back.
|
||||
|
@ -134,16 +132,15 @@ class ArticlesController < ApplicationController
|
|||
end
|
||||
end
|
||||
# action succeded
|
||||
redirect_to supplier_articles_url(@supplier, :per_page => params[:per_page])
|
||||
rescue => error
|
||||
redirect_to supplier_articles_url(@supplier, :per_page => params[:per_page]),
|
||||
:alert => I18n.t('errors.general_msg', :msg => error)
|
||||
redirect_to supplier_articles_url(@supplier, per_page: params[:per_page])
|
||||
rescue StandardError => e
|
||||
redirect_to supplier_articles_url(@supplier, per_page: params[:per_page]),
|
||||
alert: I18n.t('errors.general_msg', msg: e)
|
||||
end
|
||||
|
||||
# lets start with parsing articles from uploaded file, yeah
|
||||
# Renders the upload form
|
||||
def upload
|
||||
end
|
||||
def upload; end
|
||||
|
||||
# Update articles from a spreadsheet
|
||||
def parse_upload
|
||||
|
@ -151,13 +148,15 @@ class ArticlesController < ApplicationController
|
|||
options = { filename: uploaded_file.original_filename }
|
||||
options[:outlist_absent] = (params[:articles]['outlist_absent'] == '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?
|
||||
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
|
||||
@ignored_article_count = 0
|
||||
rescue => error
|
||||
redirect_to upload_supplier_articles_path(@supplier), :alert => I18n.t('errors.general_msg', :msg => error.message)
|
||||
rescue StandardError => e
|
||||
redirect_to upload_supplier_articles_path(@supplier), alert: I18n.t('errors.general_msg', msg: e.message)
|
||||
end
|
||||
|
||||
# sync all articles with the external database
|
||||
|
@ -165,13 +164,14 @@ class ArticlesController < ApplicationController
|
|||
def sync
|
||||
# check if there is an 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
|
||||
# sync articles against external database
|
||||
@updated_article_pairs, @outlisted_articles, @new_articles = @supplier.sync_all
|
||||
if @updated_article_pairs.empty? && @outlisted_articles.empty? && @new_articles.empty?
|
||||
redirect_to supplier_articles_path(@supplier), :notice => I18n.t('articles.controller.sync.notice')
|
||||
end
|
||||
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
|
||||
|
||||
# Updates, deletes articles when upload or sync form is submitted
|
||||
|
@ -186,7 +186,7 @@ class ArticlesController < ApplicationController
|
|||
# delete articles
|
||||
begin
|
||||
@outlisted_articles.each(&:mark_as_deleted)
|
||||
rescue
|
||||
rescue StandardError
|
||||
# raises an exception when used in current order
|
||||
has_error = true
|
||||
end
|
||||
|
@ -198,15 +198,15 @@ class ArticlesController < ApplicationController
|
|||
raise ActiveRecord::Rollback if has_error
|
||||
end
|
||||
|
||||
if !has_error
|
||||
redirect_to supplier_articles_path(@supplier), notice: I18n.t('articles.controller.update_sync.notice')
|
||||
else
|
||||
if has_error
|
||||
@updated_article_pairs = @updated_articles.map do |article|
|
||||
orig_article = Article.find(article.id)
|
||||
[article, orig_article.unequal_attributes(article)]
|
||||
end
|
||||
flash.now.alert = I18n.t('articles.controller.error_invalid')
|
||||
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
|
||||
|
||||
|
@ -218,18 +218,18 @@ class ArticlesController < ApplicationController
|
|||
q[:name_cont_all] = params.fetch(:name_cont_all_joined, '').split(' ')
|
||||
search = @supplier.shared_supplier.shared_articles.ransack(q)
|
||||
@articles = search.result.page(params[:page]).per(10)
|
||||
render :layout => false
|
||||
render layout: false
|
||||
end
|
||||
|
||||
# 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
|
||||
def import
|
||||
@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?
|
||||
if params[:direct] && !params[:article_category_id].blank? && @article.valid? && @article.save
|
||||
render :action => 'create', :layout => false
|
||||
@article.article_category_id = params[:article_category_id] if params[:article_category_id].present?
|
||||
if params[:direct] && params[:article_category_id].present? && @article.valid? && @article.save
|
||||
render action: 'create', layout: false
|
||||
else
|
||||
render :action => 'new', :layout => false
|
||||
render action: 'new', layout: false
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -9,15 +9,19 @@ module Concerns::Auth
|
|||
|
||||
def current_user
|
||||
# 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
|
||||
end
|
||||
end
|
||||
|
||||
def deny_access
|
||||
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
|
||||
|
||||
private
|
||||
|
@ -47,12 +51,7 @@ module Concerns::Auth
|
|||
|
||||
def authenticate(role = 'any')
|
||||
# Attempt to retrieve authenticated user from controller instance or session...
|
||||
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
|
||||
if current_user
|
||||
# We have an authenticated user, now check role...
|
||||
# Roles gets the user through his memberships.
|
||||
hasRole = case role
|
||||
|
@ -73,6 +72,11 @@ module Concerns::Auth
|
|||
else
|
||||
deny_access
|
||||
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
|
||||
|
||||
|
@ -116,13 +120,13 @@ module Concerns::Auth
|
|||
# if fails the user will redirected to startpage
|
||||
def authenticate_membership_or_admin(group_id = params[: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
|
||||
end
|
||||
|
||||
def authenticate_or_token(prefix, role = 'any')
|
||||
if not params[:token].blank?
|
||||
if params[:token].present?
|
||||
begin
|
||||
TokenVerifier.new(prefix).verify(params[:token])
|
||||
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.
|
||||
# @raise Api::Errors::PermissionsRequired
|
||||
def doorkeeper_authorize_roles!(*scopes)
|
||||
unless scopes.any? { |scope| doorkeeper_scope_permitted?(scope) }
|
||||
raise Api::Errors::PermissionRequired.new('Forbidden, no permission')
|
||||
end
|
||||
return if scopes.any? { |scope| doorkeeper_scope_permitted?(scope) }
|
||||
|
||||
raise Api::Errors::PermissionRequired, 'Forbidden, no permission'
|
||||
end
|
||||
|
||||
# Check whether a given OAuth scope is permitted for the current user.
|
||||
|
@ -48,9 +48,7 @@ module Concerns::AuthApi
|
|||
def doorkeeper_scope_permitted?(scope)
|
||||
scope_parts = scope.split(':')
|
||||
# user sub-scopes like +config:user+ are always permitted
|
||||
if scope_parts.last == 'user'
|
||||
return true
|
||||
end
|
||||
return true if scope_parts.last == 'user'
|
||||
|
||||
case scope_parts.first
|
||||
when 'user' then return true # access to the current user's own profile
|
||||
|
@ -64,8 +62,8 @@ module Concerns::AuthApi
|
|||
end
|
||||
|
||||
case scope
|
||||
when 'orders:read' then return true
|
||||
when 'orders:write' then return current_user.role_orders?
|
||||
when 'orders:read' then true
|
||||
when 'orders:write' then current_user.role_orders?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -24,12 +24,12 @@ module Concerns::FoodcoopScope
|
|||
elsif FoodsoftConfig.allowed_foodcoop? foodcoop
|
||||
FoodsoftConfig.select_foodcoop foodcoop
|
||||
else
|
||||
raise ActionController::RoutingError.new 'Foodcoop Not Found'
|
||||
raise ActionController::RoutingError, 'Foodcoop Not Found'
|
||||
end
|
||||
end
|
||||
|
||||
# Always stay in foodcoop url scope
|
||||
def default_url_options(options = {})
|
||||
def default_url_options(_options = {})
|
||||
super().merge({ foodcoop: FoodsoftConfig.scope })
|
||||
end
|
||||
end
|
||||
|
|
|
@ -18,7 +18,7 @@ module Concerns::Locale
|
|||
end
|
||||
|
||||
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
|
||||
|
||||
def default_language
|
||||
|
@ -30,7 +30,7 @@ module Concerns::Locale
|
|||
def select_language_according_to_priority
|
||||
language = explicitly_requested_language || session_language || user_settings_language
|
||||
language ||= browser_language unless FoodsoftConfig[:ignore_browser_locale]
|
||||
language.presence&.to_sym unless language.blank?
|
||||
language.presence&.to_sym if language.present?
|
||||
end
|
||||
|
||||
def available_locales
|
||||
|
@ -38,10 +38,10 @@ module Concerns::Locale
|
|||
end
|
||||
|
||||
def set_locale
|
||||
if available_locales.include?(select_language_according_to_priority)
|
||||
::I18n.locale = select_language_according_to_priority
|
||||
::I18n.locale = if available_locales.include?(select_language_according_to_priority)
|
||||
select_language_according_to_priority
|
||||
else
|
||||
::I18n.locale = default_language
|
||||
default_language
|
||||
end
|
||||
|
||||
locale = session[:locale] = ::I18n.locale
|
||||
|
|
|
@ -3,7 +3,7 @@ module Concerns::SendOrderPdf
|
|||
|
||||
protected
|
||||
|
||||
def send_order_pdf order, document
|
||||
def send_order_pdf(order, document)
|
||||
klass = case document
|
||||
when 'groups' then OrderByGroups
|
||||
when 'articles' then OrderByArticles
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
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
|
||||
@deliveries = @supplier.deliveries.order('date DESC')
|
||||
|
@ -15,6 +15,10 @@ class DeliveriesController < ApplicationController
|
|||
@delivery.date = Date.today # TODO: move to model/database
|
||||
end
|
||||
|
||||
def edit
|
||||
@delivery = Delivery.find(params[:id])
|
||||
end
|
||||
|
||||
def create
|
||||
@delivery = Delivery.new(params[:delivery])
|
||||
|
||||
|
@ -22,14 +26,10 @@ class DeliveriesController < ApplicationController
|
|||
flash[:notice] = I18n.t('deliveries.create.notice')
|
||||
redirect_to [@supplier, @delivery]
|
||||
else
|
||||
render :action => "new"
|
||||
render action: 'new'
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
@delivery = Delivery.find(params[:id])
|
||||
end
|
||||
|
||||
def update
|
||||
@delivery = Delivery.find(params[:id])
|
||||
|
||||
|
@ -37,7 +37,7 @@ class DeliveriesController < ApplicationController
|
|||
flash[:notice] = I18n.t('deliveries.update.notice')
|
||||
redirect_to [@supplier, @delivery]
|
||||
else
|
||||
render :action => "edit"
|
||||
render action: 'edit'
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -52,18 +52,18 @@ class DeliveriesController < ApplicationController
|
|||
def add_stock_change
|
||||
@stock_change = StockChange.new
|
||||
@stock_change.stock_article = StockArticle.find(params[:stock_article_id])
|
||||
render :layout => false
|
||||
render layout: false
|
||||
end
|
||||
|
||||
def form_on_stock_article_create # See publish/subscribe design pattern in /doc.
|
||||
@stock_article = StockArticle.find(params[:id])
|
||||
|
||||
render :layout => false
|
||||
render layout: false
|
||||
end
|
||||
|
||||
def form_on_stock_article_update # See publish/subscribe design pattern in /doc.
|
||||
@stock_article = StockArticle.find(params[:id])
|
||||
|
||||
render :layout => false
|
||||
render layout: false
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
class FeedbackController < ApplicationController
|
||||
def new
|
||||
end
|
||||
def new; end
|
||||
|
||||
def create
|
||||
if params[:message].present?
|
||||
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
|
||||
render :action => 'new'
|
||||
render action: 'new'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,7 +5,7 @@ class Finance::BalancingController < Finance::BaseController
|
|||
|
||||
def new
|
||||
@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
|
||||
|
||||
@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'
|
||||
@articles = case sort_param
|
||||
when 'name' then
|
||||
when 'name'
|
||||
@articles.order('articles.name ASC')
|
||||
when 'name_reverse' then
|
||||
when 'name_reverse'
|
||||
@articles.order('articles.name DESC')
|
||||
when 'order_number' then
|
||||
when 'order_number'
|
||||
@articles.order('articles.order_number ASC')
|
||||
when 'order_number_reverse' then
|
||||
when 'order_number_reverse'
|
||||
@articles.order('articles.order_number DESC')
|
||||
else
|
||||
@articles
|
||||
|
@ -31,13 +31,13 @@ class Finance::BalancingController < Finance::BaseController
|
|||
def new_on_order_article_create # See publish/subscribe design pattern in /doc.
|
||||
@order_article = OrderArticle.find(params[:order_article_id])
|
||||
|
||||
render :layout => false
|
||||
render layout: false
|
||||
end
|
||||
|
||||
def new_on_order_article_update # See publish/subscribe design pattern in /doc.
|
||||
@order_article = OrderArticle.find(params[:order_article_id])
|
||||
|
||||
render :layout => false
|
||||
render layout: false
|
||||
end
|
||||
|
||||
def update_summary
|
||||
|
@ -46,29 +46,29 @@ class Finance::BalancingController < Finance::BaseController
|
|||
|
||||
def edit_note
|
||||
@order = Order.find(params[:id])
|
||||
render :layout => false
|
||||
render layout: false
|
||||
end
|
||||
|
||||
def update_note
|
||||
@order = Order.find(params[:id])
|
||||
if @order.update(params[:order])
|
||||
render :layout => false
|
||||
render layout: false
|
||||
else
|
||||
render :action => :edit_note, :layout => false
|
||||
render action: :edit_note, layout: false
|
||||
end
|
||||
end
|
||||
|
||||
def edit_transport
|
||||
@order = Order.find(params[:id])
|
||||
render :layout => false
|
||||
render layout: false
|
||||
end
|
||||
|
||||
def update_transport
|
||||
@order = Order.find(params[:id])
|
||||
@order.update!(params[:order])
|
||||
redirect_to new_finance_order_path(order_id: @order.id)
|
||||
rescue => error
|
||||
redirect_to new_finance_order_path(order_id: @order.id), alert: t('errors.general_msg', msg: error.message)
|
||||
rescue StandardError => e
|
||||
redirect_to new_finance_order_path(order_id: @order.id), alert: t('errors.general_msg', msg: e.message)
|
||||
end
|
||||
|
||||
# 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])
|
||||
@type = FinancialTransactionType.find_by_id(params.permit(:type)[:type])
|
||||
@order.close!(@current_user, @type)
|
||||
redirect_to finance_order_index_url, notice: t('finance.balancing.close.notice')
|
||||
rescue => error
|
||||
redirect_to new_finance_order_url(order_id: @order.id), alert: t('finance.balancing.close.alert', message: error.message)
|
||||
redirect_to finance_order_index_url, notice: t('.notice')
|
||||
rescue StandardError => e
|
||||
redirect_to new_finance_order_url(order_id: @order.id), alert: t('.alert', message: e.message)
|
||||
end
|
||||
|
||||
# Close the order directly, without automaticly updating ordergroups account balances
|
||||
def close_direct
|
||||
@order = Order.find(params[:id])
|
||||
@order.close_direct!(@current_user)
|
||||
redirect_to finance_order_index_url, notice: t('finance.balancing.close_direct.notice')
|
||||
rescue => error
|
||||
redirect_to finance_order_index_url, alert: t('finance.balancing.close_direct.alert', message: error.message)
|
||||
redirect_to finance_order_index_url, notice: t('.notice')
|
||||
rescue StandardError => e
|
||||
redirect_to finance_order_index_url, alert: t('.alert', message: e.message)
|
||||
end
|
||||
|
||||
def close_all_direct_with_invoice
|
||||
|
@ -103,8 +103,8 @@ class Finance::BalancingController < Finance::BaseController
|
|||
count += 1
|
||||
end
|
||||
end
|
||||
redirect_to finance_order_index_url, notice: t('finance.balancing.close_all_direct_with_invoice.notice', count: count)
|
||||
rescue => error
|
||||
redirect_to finance_order_index_url, alert: t('errors.general_msg', msg: error.message)
|
||||
redirect_to finance_order_index_url, notice: t('.notice', count: count)
|
||||
rescue StandardError => e
|
||||
redirect_to finance_order_index_url, alert: t('errors.general_msg', msg: e.message)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,8 +8,8 @@ class Finance::BankAccountsController < Finance::BaseController
|
|||
@bank_account = BankAccount.find(params[:id])
|
||||
count = @bank_account.assign_unlinked_transactions
|
||||
redirect_to finance_bank_account_transactions_url(@bank_account), notice: t('.notice', count: count)
|
||||
rescue => error
|
||||
redirect_to finance_bank_account_transactions_url(@bank_account), alert: t('errors.general_msg', msg: error.message)
|
||||
rescue StandardError => e
|
||||
redirect_to finance_bank_account_transactions_url(@bank_account), alert: t('errors.general_msg', msg: e.message)
|
||||
end
|
||||
|
||||
def import
|
||||
|
@ -33,8 +33,8 @@ class Finance::BankAccountsController < Finance::BaseController
|
|||
end
|
||||
|
||||
needs_redirect = ok
|
||||
rescue => error
|
||||
flash.alert = t('errors.general_msg', msg: error.message)
|
||||
rescue StandardError => e
|
||||
flash.alert = t('errors.general_msg', msg: e.message)
|
||||
needs_redirect = true
|
||||
ensure
|
||||
return unless needs_redirect
|
||||
|
|
|
@ -3,26 +3,30 @@ class Finance::BankTransactionsController < ApplicationController
|
|||
inherit_resources
|
||||
|
||||
def index
|
||||
if params["sort"]
|
||||
sort = case params["sort"]
|
||||
when "date" then "date"
|
||||
when "amount" then "amount"
|
||||
when "financial_link" then "financial_link_id"
|
||||
when "date_reverse" then "date DESC"
|
||||
when "amount_reverse" then "amount DESC"
|
||||
when "financial_link_reverse" then "financial_link_id DESC"
|
||||
sort = if params['sort']
|
||||
case params['sort']
|
||||
when 'date' then 'date'
|
||||
when 'amount' then 'amount'
|
||||
when 'financial_link' then 'financial_link_id'
|
||||
when 'date_reverse' then 'date DESC'
|
||||
when 'amount_reverse' then 'amount DESC'
|
||||
when 'financial_link_reverse' then 'financial_link_id DESC'
|
||||
end
|
||||
else
|
||||
sort = "date DESC"
|
||||
'date DESC'
|
||||
end
|
||||
|
||||
@bank_account = BankAccount.find(params[:bank_account_id])
|
||||
@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)
|
||||
|
||||
respond_to do |format|
|
||||
format.js; format.html { render }
|
||||
format.js
|
||||
format.html { render }
|
||||
format.csv do
|
||||
send_data BankTransactionsCsv.new(@bank_transactions_all).to_csv, filename: 'transactions.csv', type: 'text/csv'
|
||||
end
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
class Finance::FinancialLinksController < Finance::BaseController
|
||||
before_action :find_financial_link, except: [:create, :incomplete]
|
||||
before_action :find_financial_link, except: %i[create incomplete]
|
||||
|
||||
def show
|
||||
@items = @financial_link.bank_transactions.map do |bt|
|
||||
|
@ -37,7 +37,7 @@ class Finance::FinancialLinksController < Finance::BaseController
|
|||
|
||||
def 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.update_attribute :financial_link, @financial_link
|
||||
end
|
||||
|
@ -72,14 +72,16 @@ class Finance::FinancialLinksController < Finance::BaseController
|
|||
|
||||
def create_financial_transaction
|
||||
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')
|
||||
rescue => error
|
||||
redirect_to finance_link_url(@financial_link), alert: t('errors.general_msg', msg: error)
|
||||
rescue StandardError => e
|
||||
redirect_to finance_link_url(@financial_link), alert: t('errors.general_msg', msg: e)
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
def add_financial_transaction
|
||||
|
@ -123,7 +125,7 @@ class Finance::FinancialLinksController < Finance::BaseController
|
|||
end
|
||||
|
||||
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 b ON a.iban = b.iban AND b.financial_link_id = #{financial_link_id.to_i}
|
||||
SQL
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
class Finance::FinancialTransactionsController < ApplicationController
|
||||
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
|
||||
# belongs_to :ordergroup
|
||||
|
||||
def index
|
||||
if params['sort']
|
||||
sort = case params['sort']
|
||||
when "date" then "created_on"
|
||||
when "note" then "note"
|
||||
when "amount" then "amount"
|
||||
when "date_reverse" then "created_on DESC"
|
||||
when "note_reverse" then "note DESC"
|
||||
when "amount_reverse" then "amount DESC"
|
||||
sort = if params['sort']
|
||||
case params['sort']
|
||||
when 'date' then 'created_on'
|
||||
when 'note' then 'note'
|
||||
when 'amount' then 'amount'
|
||||
when 'date_reverse' then 'created_on DESC'
|
||||
when 'note_reverse' then 'note DESC'
|
||||
when 'amount_reverse' then 'amount DESC'
|
||||
end
|
||||
else
|
||||
sort = "created_on DESC"
|
||||
'created_on DESC'
|
||||
end
|
||||
|
||||
@q = FinancialTransaction.ransack(params[:q])
|
||||
|
@ -26,9 +26,11 @@ class Finance::FinancialTransactionsController < ApplicationController
|
|||
@financial_transactions = @financial_transactions_all.page(params[:page]).per(@per_page)
|
||||
|
||||
respond_to do |format|
|
||||
format.js; format.html { render }
|
||||
format.js
|
||||
format.html { render }
|
||||
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
|
||||
|
@ -38,10 +40,10 @@ class Finance::FinancialTransactionsController < ApplicationController
|
|||
end
|
||||
|
||||
def new
|
||||
if @ordergroup
|
||||
@financial_transaction = @ordergroup.financial_transactions.build
|
||||
@financial_transaction = if @ordergroup
|
||||
@ordergroup.financial_transactions.build
|
||||
else
|
||||
@financial_transaction = FinancialTransaction.new
|
||||
FinancialTransaction.new
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -53,16 +55,18 @@ class Finance::FinancialTransactionsController < ApplicationController
|
|||
else
|
||||
@financial_transaction.save!
|
||||
end
|
||||
redirect_to finance_group_transactions_path(@ordergroup), notice: I18n.t('finance.financial_transactions.controller.create.notice')
|
||||
rescue ActiveRecord::RecordInvalid => error
|
||||
flash.now[:alert] = error.message
|
||||
render :action => :new
|
||||
redirect_to finance_group_transactions_path(@ordergroup),
|
||||
notice: I18n.t('finance.financial_transactions.controller.create.notice')
|
||||
rescue ActiveRecord::RecordInvalid => e
|
||||
flash.now[:alert] = e.message
|
||||
render action: :new
|
||||
end
|
||||
|
||||
def destroy
|
||||
transaction = FinancialTransaction.find(params[:id])
|
||||
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
|
||||
|
||||
def new_collection
|
||||
|
@ -88,7 +92,8 @@ class Finance::FinancialTransactionsController < ApplicationController
|
|||
|
||||
params[:financial_transactions].each do |trans|
|
||||
# ignore empty amount fields ...
|
||||
unless trans[:amount].blank?
|
||||
next if trans[:amount].blank?
|
||||
|
||||
amount = LocalizeInput.parse(trans[:amount]).to_f
|
||||
note = params[:note]
|
||||
ordergroup = Ordergroup.find(trans[:ordergroup_id])
|
||||
|
@ -99,7 +104,6 @@ class Finance::FinancialTransactionsController < ApplicationController
|
|||
ordergroup.add_financial_transaction!(amount, note, @current_user, type, financial_link)
|
||||
foodcoop_amount -= amount
|
||||
end
|
||||
end
|
||||
|
||||
if params[:create_foodcoop_transaction]
|
||||
ft = FinancialTransaction.new({
|
||||
|
@ -107,7 +111,7 @@ class Finance::FinancialTransactionsController < ApplicationController
|
|||
user: @current_user,
|
||||
amount: foodcoop_amount,
|
||||
note: params[:note],
|
||||
financial_link: financial_link,
|
||||
financial_link: financial_link
|
||||
})
|
||||
ft.save!
|
||||
end
|
||||
|
@ -117,8 +121,8 @@ class Finance::FinancialTransactionsController < ApplicationController
|
|||
|
||||
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')
|
||||
rescue => error
|
||||
flash.now[:alert] = error.message
|
||||
rescue StandardError => e
|
||||
flash.now[:alert] = e.message
|
||||
render action: :new_collection
|
||||
end
|
||||
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
class Finance::InvoicesController < ApplicationController
|
||||
before_action :authenticate_finance_or_invoices
|
||||
|
||||
before_action :find_invoice, only: [:show, :edit, :update, :destroy]
|
||||
before_action :ensure_can_edit, only: [:edit, :update, :destroy]
|
||||
before_action :find_invoice, only: %i[show edit update destroy]
|
||||
before_action :ensure_can_edit, only: %i[edit update destroy]
|
||||
|
||||
def index
|
||||
@invoices_all = Invoice.includes(:supplier, :deliveries, :orders).order('date DESC')
|
||||
@invoices = @invoices_all.page(params[:page]).per(@per_page)
|
||||
|
||||
respond_to do |format|
|
||||
format.js; format.html { render }
|
||||
format.js
|
||||
format.html { render }
|
||||
format.csv do
|
||||
send_data InvoicesCsv.new(@invoices_all).to_csv, filename: 'invoices.csv', type: 'text/csv'
|
||||
end
|
||||
|
@ -20,11 +21,10 @@ class Finance::InvoicesController < ApplicationController
|
|||
@suppliers = Supplier.includes(:invoices).where('invoices.paid_on IS NULL').references(:invoices)
|
||||
end
|
||||
|
||||
def show
|
||||
end
|
||||
def show; end
|
||||
|
||||
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.orders << Order.find_by_id(params[:order_id]) if params[:order_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
|
||||
fill_deliveries_and_orders_collection params[:invoice_id], params[:supplier_id]
|
||||
render :layout => false
|
||||
render layout: false
|
||||
end
|
||||
|
||||
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)
|
||||
@orders_collection = Order.where('invoice_id = ? OR (invoice_id IS NULL AND supplier_id = ?)', invoice_id, supplier_id).order(ends: :desc).limit(25)
|
||||
@deliveries_collection = Delivery.where('invoice_id = ? OR (invoice_id IS NULL AND supplier_id = ?)', invoice_id,
|
||||
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
|
||||
|
||||
def create
|
||||
|
@ -58,7 +60,7 @@ class Finance::InvoicesController < ApplicationController
|
|||
end
|
||||
else
|
||||
fill_deliveries_and_orders_collection @invoice.id, @invoice.supplier_id
|
||||
render :action => "new"
|
||||
render action: 'new'
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -81,7 +83,7 @@ class Finance::InvoicesController < ApplicationController
|
|||
@invoice = Invoice.find(params[:invoice_id])
|
||||
type = MIME::Types[@invoice.attachment_mime].first
|
||||
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
|
||||
|
||||
private
|
||||
|
@ -92,8 +94,8 @@ class Finance::InvoicesController < ApplicationController
|
|||
|
||||
# Returns true if @current_user can edit the invoice..
|
||||
def ensure_can_edit
|
||||
unless @invoice.user_can_edit?(current_user)
|
||||
return if @invoice.user_can_edit?(current_user)
|
||||
|
||||
deny_access
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
class Finance::OrdergroupsController < Finance::BaseController
|
||||
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
|
||||
sort = m[:col]
|
||||
sort += ' DESC' if m[:reverse]
|
||||
else
|
||||
sort = "name"
|
||||
sort = 'name'
|
||||
end
|
||||
|
||||
@ordergroups = Ordergroup.undeleted.order(sort)
|
||||
|
|
|
@ -1,20 +1,16 @@
|
|||
class Foodcoop::OrdergroupsController < ApplicationController
|
||||
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]}%")
|
||||
end
|
||||
@ordergroups = @ordergroups.where('name LIKE ?', "%#{params[:name]}%") if params[:name].present? # Search by name
|
||||
|
||||
if params[:only_active] # Select only active groups
|
||||
@ordergroups = @ordergroups.active
|
||||
end
|
||||
@ordergroups = @ordergroups.active if params[:only_active] # Select only active groups
|
||||
|
||||
@ordergroups = @ordergroups.page(params[:page]).per(@per_page)
|
||||
|
||||
respond_to do |format|
|
||||
format.html # index.html.erb
|
||||
format.js { render :layout => false }
|
||||
format.js { render layout: false }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,19 +1,20 @@
|
|||
class Foodcoop::UsersController < ApplicationController
|
||||
def index
|
||||
@users = User.undeleted.sort_by_param(params["sort"])
|
||||
@users = User.undeleted.sort_by_param(params['sort'])
|
||||
|
||||
# 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]
|
||||
@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
|
||||
|
||||
@users = @users.page(params[:page]).per(@per_page)
|
||||
|
||||
respond_to do |format|
|
||||
format.html # index.html.haml
|
||||
format.js { render :layout => false } # index.js.erb
|
||||
format.js { render layout: false } # index.js.erb
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
class Foodcoop::WorkgroupsController < ApplicationController
|
||||
before_action :authenticate_membership_or_admin,
|
||||
:except => [:index]
|
||||
except: [:index]
|
||||
|
||||
def index
|
||||
@workgroups = Workgroup.order("name")
|
||||
@workgroups = Workgroup.order('name')
|
||||
end
|
||||
|
||||
def edit
|
||||
|
@ -13,9 +13,9 @@ class Foodcoop::WorkgroupsController < ApplicationController
|
|||
def update
|
||||
@workgroup = Workgroup.find(params[:id])
|
||||
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
|
||||
render :action => 'edit'
|
||||
render action: 'edit'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
class GroupOrderArticlesController < ApplicationController
|
||||
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
|
||||
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
class GroupOrdersController < ApplicationController
|
||||
# Security
|
||||
before_action :ensure_ordergroup_member
|
||||
before_action :ensure_open_order, :only => [:new, :create, :edit, :update, :order, :stock_order, :saveOrder]
|
||||
before_action :ensure_my_group_order, only: [:show, :edit, :update]
|
||||
before_action :enough_apples?, only: [:new, :create]
|
||||
before_action :ensure_open_order, only: %i[new create edit update order stock_order saveOrder]
|
||||
before_action :ensure_my_group_order, only: %i[show edit update]
|
||||
before_action :enough_apples?, only: %i[new create]
|
||||
|
||||
# Index page.
|
||||
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)
|
||||
end
|
||||
|
||||
def show
|
||||
@order = @group_order.order
|
||||
end
|
||||
|
||||
def new
|
||||
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
|
||||
end
|
||||
|
||||
|
@ -23,34 +31,26 @@ class GroupOrdersController < ApplicationController
|
|||
@group_order = GroupOrder.new(params[:group_order])
|
||||
begin
|
||||
@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
|
||||
redirect_to group_orders_url, :alert => I18n.t('group_orders.create.error_stale')
|
||||
rescue => exception
|
||||
logger.error('Failed to update order: ' + exception.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_stale')
|
||||
rescue StandardError => e
|
||||
logger.error('Failed to update order: ' + e.message)
|
||||
redirect_to group_orders_url, alert: I18n.t('group_orders.create.error_general')
|
||||
end
|
||||
end
|
||||
|
||||
def show
|
||||
@order = @group_order.order
|
||||
end
|
||||
|
||||
def edit
|
||||
@ordering_data = @group_order.load_data
|
||||
end
|
||||
|
||||
def update
|
||||
@group_order.attributes = params[:group_order]
|
||||
@group_order.updated_by = current_user
|
||||
begin
|
||||
@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
|
||||
redirect_to group_orders_url, :alert => I18n.t('group_orders.update.error_stale')
|
||||
rescue => exception
|
||||
logger.error('Failed to update order: ' + exception.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_stale')
|
||||
rescue StandardError => e
|
||||
logger.error('Failed to update order: ' + e.message)
|
||||
redirect_to group_orders_url, alert: I18n.t('group_orders.update.error_general')
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -74,16 +74,16 @@ class GroupOrdersController < ApplicationController
|
|||
# Used as a :before_action by OrdersController.
|
||||
def ensure_ordergroup_member
|
||||
@ordergroup = @current_user.ordergroup
|
||||
if @ordergroup.nil?
|
||||
redirect_to root_url, :alert => I18n.t('group_orders.errors.no_member')
|
||||
end
|
||||
return unless @ordergroup.nil?
|
||||
|
||||
redirect_to root_url, alert: I18n.t('group_orders.errors.no_member')
|
||||
end
|
||||
|
||||
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?
|
||||
flash[:notice] = I18n.t('group_orders.errors.closed')
|
||||
redirect_to :action => 'index'
|
||||
redirect_to action: 'index'
|
||||
end
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
redirect_to group_orders_url, alert: I18n.t('group_orders.errors.notfound')
|
||||
|
@ -91,18 +91,18 @@ class GroupOrdersController < ApplicationController
|
|||
|
||||
def ensure_my_group_order
|
||||
@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
|
||||
end
|
||||
|
||||
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,
|
||||
stop_ordering_under: FoodsoftConfig[:stop_ordering_under])
|
||||
end
|
||||
end
|
||||
|
||||
def order_id_param
|
||||
params[:order_id] || (params[:group_order] && params[:group_order][:order_id])
|
||||
|
|
|
@ -9,8 +9,7 @@ class HomeController < ApplicationController
|
|||
@unassigned_tasks = Task.order(:due_date).next_unassigned_tasks_for(current_user)
|
||||
end
|
||||
|
||||
def profile
|
||||
end
|
||||
def profile; end
|
||||
|
||||
def reference_calculator
|
||||
if current_user.ordergroup
|
||||
|
@ -36,40 +35,43 @@ class HomeController < ApplicationController
|
|||
@user = @current_user
|
||||
@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)
|
||||
|
||||
if params['sort']
|
||||
sort = case params['sort']
|
||||
when "date" then "created_on"
|
||||
when "note" then "note"
|
||||
when "amount" then "amount"
|
||||
when "date_reverse" then "created_on DESC"
|
||||
when "note_reverse" then "note DESC"
|
||||
when "amount_reverse" then "amount DESC"
|
||||
sort = if params['sort']
|
||||
case params['sort']
|
||||
when 'date' then 'created_on'
|
||||
when 'note' then 'note'
|
||||
when 'amount' then 'amount'
|
||||
when 'date_reverse' then 'created_on DESC'
|
||||
when 'note_reverse' then 'note DESC'
|
||||
when 'amount_reverse' then 'amount DESC'
|
||||
end
|
||||
else
|
||||
sort = "created_on DESC"
|
||||
'created_on DESC'
|
||||
end
|
||||
|
||||
@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
|
||||
|
||||
# cancel personal memberships direct from the myProfile-page
|
||||
def cancel_membership
|
||||
if params[:membership_id]
|
||||
membership = @current_user.memberships.find(params[:membership_id])
|
||||
membership = if params[:membership_id]
|
||||
@current_user.memberships.find(params[:membership_id])
|
||||
else
|
||||
membership = @current_user.memberships.find_by_group_id!(params[:group_id])
|
||||
@current_user.memberships.find_by_group_id!(params[:group_id])
|
||||
end
|
||||
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
|
||||
|
||||
protected
|
||||
|
@ -82,8 +84,8 @@ class HomeController < ApplicationController
|
|||
end
|
||||
|
||||
def ordergroup_params
|
||||
if params[:user][:ordergroup]
|
||||
return unless params[:user][:ordergroup]
|
||||
|
||||
params.require(:user).require(:ordergroup).permit(:contact_address)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,7 +3,7 @@ class InvitesController < ApplicationController
|
|||
before_action -> { require_config_disabled :disable_invite }
|
||||
|
||||
def new
|
||||
@invite = Invite.new(:user => @current_user, :group => @group)
|
||||
@invite = Invite.new(user: @current_user, group: @group)
|
||||
end
|
||||
|
||||
def create
|
||||
|
@ -27,6 +27,10 @@ class InvitesController < ApplicationController
|
|||
protected
|
||||
|
||||
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
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
class LoginController < ApplicationController
|
||||
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.
|
||||
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".
|
||||
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
|
||||
end
|
||||
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.
|
||||
|
||||
if (user = User.undeleted.find_by_email(params[:user][:email]))
|
||||
user.request_password_reset!
|
||||
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
|
||||
|
||||
# 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.
|
||||
def new_password
|
||||
end
|
||||
def new_password; end
|
||||
|
||||
# Sets 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_expires = nil
|
||||
@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
|
||||
render :new_password
|
||||
end
|
||||
|
@ -50,14 +47,14 @@ class LoginController < ApplicationController
|
|||
@user = User.new(params[:user])
|
||||
@user.email = @invite.email
|
||||
if @user.save
|
||||
Membership.new(:user => @user, :group => @invite.group).save!
|
||||
Membership.new(user: @user, group: @invite.group).save!
|
||||
@invite.destroy
|
||||
session[:locale] = @user.locale
|
||||
redirect_to login_url, notice: I18n.t('login.controller.accept_invitation.notice')
|
||||
end
|
||||
end
|
||||
else
|
||||
@user = User.new(:email => @invite.email)
|
||||
@user = User.new(email: @invite.email)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -65,8 +62,8 @@ class LoginController < ApplicationController
|
|||
|
||||
def validate_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
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
class OrderArticlesController < ApplicationController
|
||||
before_action :fetch_order, except: :destroy
|
||||
before_action :authenticate_finance_or_invoices, except: [:new, :create]
|
||||
before_action :authenticate_finance_orders_or_pickup, except: [:edit, :update, :destroy]
|
||||
before_action :authenticate_finance_or_invoices, except: %i[new create]
|
||||
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
|
||||
|
||||
|
@ -9,28 +9,26 @@ class OrderArticlesController < ApplicationController
|
|||
@order_article = @order.order_articles.build(params[:order_article])
|
||||
end
|
||||
|
||||
def edit
|
||||
@order_article = OrderArticle.find(params[:id])
|
||||
end
|
||||
|
||||
def create
|
||||
# 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
|
||||
# given mentioning that the article already exists, which is desired.
|
||||
@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])
|
||||
end
|
||||
@order_article = @order.order_articles.where(article_id: params[:order_article][:article_id]).first
|
||||
@order_article = @order.order_articles.build(params[:order_article]) unless @order_article && @order_article.units_to_order == 0
|
||||
@order_article.save!
|
||||
rescue
|
||||
rescue StandardError
|
||||
render action: :new
|
||||
end
|
||||
|
||||
def edit
|
||||
@order_article = OrderArticle.find(params[:id])
|
||||
end
|
||||
|
||||
def update
|
||||
@order_article = OrderArticle.find(params[:id])
|
||||
begin
|
||||
@order_article.update_article_and_price!(params[:order_article], params[:article], params[:article_price])
|
||||
rescue
|
||||
rescue StandardError
|
||||
render action: :edit
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
class OrderCommentsController < ApplicationController
|
||||
def new
|
||||
@order = Order.find(params[:order_id])
|
||||
@order_comment = @order.comments.build(:user => current_user)
|
||||
@order_comment = @order.comments.build(user: current_user)
|
||||
end
|
||||
|
||||
def create
|
||||
@order_comment = OrderComment.new(params[:order_comment])
|
||||
if @order_comment.save
|
||||
render :layout => false
|
||||
render layout: false
|
||||
else
|
||||
render :action => :new, :layout => false
|
||||
render action: :new, layout: false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,24 +5,25 @@ class OrdersController < ApplicationController
|
|||
include Concerns::SendOrderPdf
|
||||
|
||||
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 :remove_empty_article, only: [:create, :update]
|
||||
before_action :authenticate_orders,
|
||||
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
|
||||
def index
|
||||
@open_orders = Order.open.includes(:supplier)
|
||||
@finished_orders = Order.finished_not_closed.includes(:supplier)
|
||||
@per_page = 15
|
||||
if params['sort']
|
||||
sort = case params['sort']
|
||||
when "supplier" then "suppliers.name, ends DESC"
|
||||
when "pickup" then "pickup DESC"
|
||||
when "ends" then "ends DESC"
|
||||
when "supplier_reverse" then "suppliers.name DESC"
|
||||
when "ends_reverse" then "ends"
|
||||
sort = if params['sort']
|
||||
case params['sort']
|
||||
when 'supplier' then 'suppliers.name, ends DESC'
|
||||
when 'pickup' then 'pickup DESC'
|
||||
when 'ends' then 'ends DESC'
|
||||
when 'supplier_reverse' then 'suppliers.name DESC'
|
||||
when 'ends_reverse' then 'ends'
|
||||
end
|
||||
else
|
||||
sort = "ends DESC"
|
||||
'ends DESC'
|
||||
end
|
||||
@suppliers = Supplier.having_articles.order('suppliers.name')
|
||||
@orders = Order.closed.includes(:supplier).reorder(sort).page(params[:page]).per(@per_page)
|
||||
|
@ -43,7 +44,7 @@ class OrdersController < ApplicationController
|
|||
respond_to do |format|
|
||||
format.html
|
||||
format.js do
|
||||
render :layout => false
|
||||
render layout: false
|
||||
end
|
||||
format.pdf do
|
||||
send_order_pdf @order, params[:document]
|
||||
|
@ -66,8 +67,14 @@ class OrdersController < ApplicationController
|
|||
else
|
||||
@order = Order.new(supplier_id: params[:supplier_id]).init_dates
|
||||
end
|
||||
rescue => error
|
||||
redirect_to orders_url, alert: t('errors.general_msg', msg: error.message)
|
||||
rescue StandardError => e
|
||||
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
|
||||
|
||||
# Save a new order.
|
||||
|
@ -81,31 +88,25 @@ class OrdersController < ApplicationController
|
|||
redirect_to @order
|
||||
else
|
||||
logger.debug "[debug] order errors: #{@order.errors.messages}"
|
||||
render :action => 'new'
|
||||
render action: 'new'
|
||||
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.
|
||||
def update
|
||||
@order = Order.find params[:id]
|
||||
if @order.update(params[:order].merge(updated_by: current_user))
|
||||
flash[:notice] = I18n.t('orders.update.notice')
|
||||
redirect_to :action => 'show', :id => @order
|
||||
redirect_to action: 'show', id: @order
|
||||
else
|
||||
render :action => 'edit'
|
||||
render action: 'edit'
|
||||
end
|
||||
end
|
||||
|
||||
# Delete an order.
|
||||
def destroy
|
||||
Order.find(params[:id]).destroy
|
||||
redirect_to :action => 'index'
|
||||
redirect_to action: 'index'
|
||||
end
|
||||
|
||||
# Finish a current order.
|
||||
|
@ -113,8 +114,8 @@ class OrdersController < ApplicationController
|
|||
order = Order.find(params[:id])
|
||||
order.finish!(@current_user)
|
||||
redirect_to order, notice: I18n.t('orders.finish.notice')
|
||||
rescue => error
|
||||
redirect_to orders_url, alert: I18n.t('errors.general_msg', :msg => error.message)
|
||||
rescue StandardError => e
|
||||
redirect_to orders_url, alert: I18n.t('errors.general_msg', msg: e.message)
|
||||
end
|
||||
|
||||
# Send a order to the supplier.
|
||||
|
@ -122,20 +123,18 @@ class OrdersController < ApplicationController
|
|||
order = Order.find(params[:id])
|
||||
order.send_to_supplier!(@current_user)
|
||||
redirect_to order, notice: I18n.t('orders.send_to_supplier.notice')
|
||||
rescue => error
|
||||
redirect_to order, alert: I18n.t('errors.general_msg', :msg => error.message)
|
||||
rescue StandardError => e
|
||||
redirect_to order, alert: I18n.t('errors.general_msg', msg: e.message)
|
||||
end
|
||||
|
||||
def receive
|
||||
@order = Order.find(params[:id])
|
||||
unless request.post?
|
||||
@order_articles = @order.order_articles.ordered_or_member.includes(:article).order('articles.order_number, articles.name')
|
||||
else
|
||||
if request.post?
|
||||
Order.transaction do
|
||||
s = update_order_amounts
|
||||
@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
|
||||
NotifyReceivedOrderJob.perform_later(@order)
|
||||
if current_user.role_orders? || current_user.role_finance?
|
||||
|
@ -145,23 +144,25 @@ class OrdersController < ApplicationController
|
|||
else
|
||||
redirect_to receive_order_path(@order)
|
||||
end
|
||||
else
|
||||
@order_articles = @order.order_articles.ordered_or_member.includes(:article).order('articles.order_number, articles.name')
|
||||
end
|
||||
end
|
||||
|
||||
def receive_on_order_article_create # See publish/subscribe design pattern in /doc.
|
||||
@order_article = OrderArticle.find(params[:order_article_id])
|
||||
render :layout => false
|
||||
render layout: false
|
||||
end
|
||||
|
||||
def receive_on_order_article_update # See publish/subscribe design pattern in /doc.
|
||||
@order_article = OrderArticle.find(params[:order_article_id])
|
||||
render :layout => false
|
||||
render layout: false
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def update_order_amounts
|
||||
return if not params[:order_articles]
|
||||
return unless params[:order_articles]
|
||||
|
||||
# where to leave remainder during redistribution
|
||||
rest_to = []
|
||||
|
@ -176,35 +177,42 @@ class OrdersController < ApplicationController
|
|||
# "MySQL lock timeout exceeded" errors. It's ok to do
|
||||
# this article-by-article anway.
|
||||
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
|
||||
# which makes received_changed? not work anymore
|
||||
oa.attributes = oa_params
|
||||
if oa.units_received_changed?
|
||||
counts[0] += 1
|
||||
unless oa.units_received.blank?
|
||||
if oa.units_received.present?
|
||||
cunits[0] += oa.units_received * oa.article.unit_quantity
|
||||
oacounts = oa.redistribute oa.units_received * oa.price.unit_quantity, rest_to
|
||||
oacounts.each_with_index { |c, i| cunits[i + 1] += c; counts[i + 1] += 1 if c > 0 }
|
||||
oacounts.each_with_index do |c, i|
|
||||
cunits[i + 1] += c
|
||||
counts[i + 1] += 1 if c > 0
|
||||
end
|
||||
end
|
||||
end
|
||||
oa.save!
|
||||
end
|
||||
end
|
||||
return nil if counts[0] == 0
|
||||
|
||||
notice = []
|
||||
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]
|
||||
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
|
||||
notice.join(', ')
|
||||
end
|
||||
|
||||
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
|
||||
|
|
|
@ -12,10 +12,10 @@ class SessionsController < ApplicationController
|
|||
user = User.authenticate(params[:nick], params[:password])
|
||||
if user
|
||||
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
|
||||
flash.now.alert = I18n.t(FoodsoftConfig[:use_nick] ? 'sessions.login_invalid_nick' : 'sessions.login_invalid_email')
|
||||
render "new"
|
||||
render 'new'
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -24,7 +24,7 @@ class SessionsController < ApplicationController
|
|||
if FoodsoftConfig[:logout_redirect_url].present?
|
||||
redirect_to FoodsoftConfig[:logout_redirect_url]
|
||||
else
|
||||
redirect_to login_url, :notice => I18n.t('sessions.logged_out')
|
||||
redirect_to login_url, notice: I18n.t('sessions.logged_out')
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -7,21 +7,21 @@ class StockTakingsController < ApplicationController
|
|||
|
||||
def 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
|
||||
|
||||
def new_on_stock_article_create # See publish/subscribe design pattern in /doc.
|
||||
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
|
||||
|
||||
def create
|
||||
create!(:notice => I18n.t('stock_takings.create.notice'))
|
||||
create!(notice: I18n.t('stock_takings.create.notice'))
|
||||
end
|
||||
|
||||
def update
|
||||
update!(:notice => I18n.t('stock_takings.update.notice'))
|
||||
update!(notice: I18n.t('stock_takings.update.notice'))
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,57 +7,13 @@ class StockitController < ApplicationController
|
|||
def index_on_stock_article_create # See publish/subscribe design pattern in /doc.
|
||||
@stock_article = StockArticle.find(params[:id])
|
||||
|
||||
render :layout => false
|
||||
render layout: false
|
||||
end
|
||||
|
||||
def index_on_stock_article_update # See publish/subscribe design pattern in /doc.
|
||||
@stock_article = StockArticle.find(params[:id])
|
||||
|
||||
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
|
||||
render layout: false
|
||||
end
|
||||
|
||||
def show
|
||||
|
@ -65,24 +21,68 @@ class StockitController < ApplicationController
|
|||
@stock_changes = @stock_article.stock_changes.order('stock_changes.created_at DESC')
|
||||
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.
|
||||
@stock_article = StockArticle.find(params[:id])
|
||||
|
||||
render :layout => false
|
||||
render layout: false
|
||||
end
|
||||
|
||||
def destroy
|
||||
@stock_article = StockArticle.find(params[:id])
|
||||
@stock_article.mark_as_deleted
|
||||
render :layout => false
|
||||
rescue => error
|
||||
render :partial => "destroy_fail", :layout => false,
|
||||
:locals => { :fail_msg => I18n.t('errors.general_msg', :msg => error.message) }
|
||||
render layout: false
|
||||
rescue StandardError => e
|
||||
render partial: 'destroy_fail', layout: false,
|
||||
locals: { fail_msg: I18n.t('errors.general_msg', msg: e.message) }
|
||||
end
|
||||
|
||||
# TODO: Fix this!!
|
||||
def articles_search
|
||||
@articles = Article.not_in_stock.limit(8).where('name LIKE ?', "%#{params[:term]}%")
|
||||
render :json => @articles.map(&:name)
|
||||
render json: @articles.map(&:name)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,7 +9,7 @@ class StylesController < ApplicationController
|
|||
def foodcoop
|
||||
css = FoodsoftConfig[:custom_css]
|
||||
if css.blank?
|
||||
render body: nil, content_type: 'text/css', status: 404
|
||||
render body: nil, content_type: 'text/css', status: :not_found
|
||||
else
|
||||
expires_in 1.week, public: true if params[:md5].present?
|
||||
render body: css, content_type: 'text/css'
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
class SuppliersController < ApplicationController
|
||||
before_action :authenticate_suppliers, :except => [:index, :list]
|
||||
before_action :authenticate_suppliers, except: %i[index list]
|
||||
helper :deliveries
|
||||
|
||||
def index
|
||||
|
@ -24,6 +24,10 @@ class SuppliersController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
@supplier = Supplier.find(params[:id])
|
||||
end
|
||||
|
||||
def create
|
||||
@supplier = Supplier.new(supplier_params)
|
||||
@supplier.supplier_category ||= SupplierCategory.first
|
||||
|
@ -31,21 +35,17 @@ class SuppliersController < ApplicationController
|
|||
flash[:notice] = I18n.t('suppliers.create.notice')
|
||||
redirect_to suppliers_path
|
||||
else
|
||||
render :action => 'new'
|
||||
render action: 'new'
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
@supplier = Supplier.find(params[:id])
|
||||
end
|
||||
|
||||
def update
|
||||
@supplier = Supplier.find(params[:id])
|
||||
if @supplier.update(supplier_params)
|
||||
flash[:notice] = I18n.t('suppliers.update.notice')
|
||||
redirect_to @supplier
|
||||
else
|
||||
render :action => 'edit'
|
||||
render action: 'edit'
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -54,8 +54,8 @@ class SuppliersController < ApplicationController
|
|||
@supplier.mark_as_deleted
|
||||
flash[:notice] = I18n.t('suppliers.destroy.notice')
|
||||
redirect_to suppliers_path
|
||||
rescue => e
|
||||
flash[:error] = I18n.t('errors.general_msg', :msg => e.message)
|
||||
rescue StandardError => e
|
||||
flash[:error] = I18n.t('errors.general_msg', msg: e.message)
|
||||
redirect_to @supplier
|
||||
end
|
||||
|
||||
|
|
|
@ -11,35 +11,33 @@ class TasksController < ApplicationController
|
|||
@accepted_tasks = Task.accepted_tasks_for(current_user)
|
||||
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
|
||||
@task = Task.find(params[:id])
|
||||
end
|
||||
|
||||
def new
|
||||
@task = Task.new(current_user_id: current_user.id)
|
||||
end
|
||||
|
||||
def edit
|
||||
@task = Task.find(params[:id])
|
||||
@periodic = !!params[:periodic]
|
||||
@task.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)
|
||||
@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
|
||||
@task = Task.find(params[:id])
|
||||
task_group = @task.periodic_task_group
|
||||
|
@ -50,16 +48,14 @@ class TasksController < ApplicationController
|
|||
if @task.errors.empty? && @task.save
|
||||
task_group.update_tasks_including(@task, prev_due_date) if params[:periodic]
|
||||
flash[:notice] = I18n.t('tasks.update.notice')
|
||||
if was_periodic && !@task.periodic?
|
||||
flash[:notice] = I18n.t('tasks.update.notice_converted')
|
||||
end
|
||||
flash[:notice] = I18n.t('tasks.update.notice_converted') if was_periodic && !@task.periodic?
|
||||
if @task.workgroup
|
||||
redirect_to workgroup_tasks_url(workgroup_id: @task.workgroup_id)
|
||||
else
|
||||
redirect_to tasks_url
|
||||
end
|
||||
else
|
||||
render :template => "tasks/edit"
|
||||
render template: 'tasks/edit'
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -75,7 +71,7 @@ class TasksController < ApplicationController
|
|||
end
|
||||
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
|
||||
|
||||
# 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)
|
||||
ass.update_attribute(:accepted, true)
|
||||
else
|
||||
task.assignments.create(:user => current_user, :accepted => true)
|
||||
task.assignments.create(user: current_user, accepted: true)
|
||||
end
|
||||
redirect_to user_tasks_path, :notice => I18n.t('tasks.accept.notice')
|
||||
redirect_to user_tasks_path, notice: I18n.t('tasks.accept.notice')
|
||||
end
|
||||
|
||||
# deletes assignment between current_user and given taskcurrent_user_id: current_user.id
|
||||
def reject
|
||||
Task.find(params[:id]).users.delete(current_user)
|
||||
redirect_to :action => "index"
|
||||
redirect_to action: 'index'
|
||||
end
|
||||
|
||||
def set_done
|
||||
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
|
||||
|
||||
# Shows all tasks, which are already done
|
||||
|
@ -109,9 +105,9 @@ class TasksController < ApplicationController
|
|||
# shows workgroup (normal group) to edit weekly_tasks_template
|
||||
def workgroup
|
||||
@group = Group.find(params[:workgroup_id])
|
||||
if @group.is_a? Ordergroup
|
||||
redirect_to tasks_url, :alert => I18n.t('tasks.error_not_found')
|
||||
end
|
||||
return unless @group.is_a? Ordergroup
|
||||
|
||||
redirect_to tasks_url, alert: I18n.t('tasks.error_not_found')
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -3,7 +3,7 @@ class UsersController < ApplicationController
|
|||
def index
|
||||
@users = User.undeleted.natural_search(params[:q])
|
||||
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
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
class OrderByArticles < OrderPdf
|
||||
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
|
||||
|
||||
def title
|
||||
I18n.t('documents.order_by_articles.title', :name => order.name,
|
||||
:date => order.ends.strftime(I18n.t('date.formats.default')))
|
||||
I18n.t('documents.order_by_articles.title', name: order.name,
|
||||
date: order.ends.strftime(I18n.t('date.formats.default')))
|
||||
end
|
||||
|
||||
def body
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
class OrderByGroups < OrderPdf
|
||||
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
|
||||
|
||||
def title
|
||||
I18n.t('documents.order_by_groups.title', :name => order.name,
|
||||
:date => order.ends.strftime(I18n.t('date.formats.default')))
|
||||
I18n.t('documents.order_by_groups.title', name: order.name,
|
||||
date: order.ends.strftime(I18n.t('date.formats.default')))
|
||||
end
|
||||
|
||||
def body
|
||||
|
|
|
@ -2,7 +2,7 @@ class OrderFax < OrderPdf
|
|||
BATCH_SIZE = 250
|
||||
|
||||
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
|
||||
|
||||
def title
|
||||
|
@ -20,16 +20,18 @@ class OrderFax < OrderPdf
|
|||
move_down 5
|
||||
text "#{contact[:zip_code]} #{contact[:city]}", size: fontsize(9), align: :right
|
||||
move_down 5
|
||||
unless order.supplier.try(:customer_number).blank?
|
||||
text "#{Supplier.human_attribute_name :customer_number}: #{order.supplier[:customer_number]}", size: fontsize(9), align: :right
|
||||
if order.supplier.try(:customer_number).present?
|
||||
text "#{Supplier.human_attribute_name :customer_number}: #{order.supplier[:customer_number]}",
|
||||
size: fontsize(9), align: :right
|
||||
move_down 5
|
||||
end
|
||||
unless contact[:phone].blank?
|
||||
if contact[:phone].present?
|
||||
text "#{Supplier.human_attribute_name :phone}: #{contact[:phone]}", size: fontsize(9), align: :right
|
||||
move_down 5
|
||||
end
|
||||
unless contact[:email].blank?
|
||||
text "#{Supplier.human_attribute_name :email}: #{contact[:email]}", size: fontsize(9), align: :right
|
||||
if contact[:email].present?
|
||||
text "#{Supplier.human_attribute_name :email}: #{contact[:email]}", size: fontsize(9),
|
||||
align: :right
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -38,7 +40,7 @@ class OrderFax < OrderPdf
|
|||
text order.name
|
||||
move_down 5
|
||||
text order.supplier.try(:address).to_s
|
||||
unless order.supplier.try(:fax).blank?
|
||||
if order.supplier.try(:fax).present?
|
||||
move_down 5
|
||||
text "#{Supplier.human_attribute_name :fax}: #{order.supplier[:fax]}"
|
||||
end
|
||||
|
@ -50,7 +52,7 @@ class OrderFax < OrderPdf
|
|||
move_down 10
|
||||
text "#{Delivery.human_attribute_name :date}:"
|
||||
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]}"
|
||||
move_down 10
|
||||
end
|
||||
|
@ -78,8 +80,8 @@ class OrderFax < OrderPdf
|
|||
table.row(0).border_bottom_width = 2
|
||||
table.columns(1).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).borders = [:top, :bottom, :left]
|
||||
table.row(data.length - 1).columns(0..5).borders = %i[top bottom]
|
||||
table.row(data.length - 1).columns(0).borders = %i[top bottom left]
|
||||
table.row(data.length - 1).border_top_width = 2
|
||||
end
|
||||
# font_size: fontsize(8),
|
||||
|
@ -98,7 +100,7 @@ class OrderFax < OrderPdf
|
|||
.preload(:article, :article_price)
|
||||
end
|
||||
|
||||
def each_order_article
|
||||
order_articles.find_each_with_order(batch_size: BATCH_SIZE) { |oa| yield oa }
|
||||
def each_order_article(&block)
|
||||
order_articles.find_each_with_order(batch_size: BATCH_SIZE, &block)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,12 +3,12 @@ class OrderMatrix < OrderPdf
|
|||
PLACEHOLDER_CHAR = 'X'
|
||||
|
||||
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
|
||||
|
||||
def title
|
||||
I18n.t('documents.order_matrix.title', :name => @order.name,
|
||||
:date => @order.ends.strftime(I18n.t('date.formats.default')))
|
||||
I18n.t('documents.order_matrix.title', name: @order.name,
|
||||
date: @order.ends.strftime(I18n.t('date.formats.default')))
|
||||
end
|
||||
|
||||
def body
|
||||
|
@ -87,7 +87,7 @@ class OrderMatrix < OrderPdf
|
|||
table.cells.border_width = 0.5
|
||||
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(1..-1).height = row_height_1
|
||||
table.column(0..1).borders = []
|
||||
|
@ -106,7 +106,7 @@ class OrderMatrix < OrderPdf
|
|||
table.column(2 + idx).border_width = 2
|
||||
end
|
||||
|
||||
table.row_colors = ['dddddd', 'ffffff']
|
||||
table.row_colors = %w[dddddd ffffff]
|
||||
end
|
||||
|
||||
first_page = false
|
||||
|
|
|
@ -28,7 +28,11 @@ module Admin::ConfigsHelper
|
|||
options[:default] = options[:input_html].delete(:value)
|
||||
return form.input key, options, &block
|
||||
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
|
||||
end
|
||||
|
||||
|
@ -57,11 +61,12 @@ module Admin::ConfigsHelper
|
|||
unchecked_value = options.delete(:unchecked_value) || '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
|
||||
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
|
||||
options[:value] = FoodsoftDateUtil.rule_from(options[:value])
|
||||
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
|
||||
form.select_recurring key, options.delete(:rules).uniq, options
|
||||
else
|
||||
|
@ -73,7 +78,7 @@ module Admin::ConfigsHelper
|
|||
# @param form [ActionView::Helpers::FormBuilder] Form object.
|
||||
# @param key [Symbol, String] Configuration key of a boolean (e.g. +use_messages+).
|
||||
# @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
|
||||
lbl = options[:label] || config_input_label(form, key)
|
||||
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, {})
|
||||
end
|
||||
end
|
||||
fields = content_tag(:fieldset, id: "#{key}-fields", class: "collapse#{' in' if @cfg[key]}") do
|
||||
yield
|
||||
end
|
||||
fields = content_tag(:fieldset, id: "#{key}-fields", class: "collapse#{' in' if @cfg[key]}", &block)
|
||||
head + fields
|
||||
end
|
||||
|
||||
|
@ -127,7 +130,7 @@ module Admin::ConfigsHelper
|
|||
# tooltip with help info to the right
|
||||
cfg_path = form.lookup_model_names[1..-1] + [key]
|
||||
tooltip = I18n.t("config.hints.#{cfg_path.map(&:to_s).join('.')}", default: '')
|
||||
unless tooltip.blank?
|
||||
if tooltip.present?
|
||||
options[:data] ||= {}
|
||||
options[:data][:toggle] ||= 'tooltip'
|
||||
options[:data][:placement] ||= 'right'
|
||||
|
|
|
@ -2,9 +2,7 @@ module Admin::OrdergroupsHelper
|
|||
def ordergroup_members_title(ordergroup)
|
||||
s = ''
|
||||
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
|
||||
end
|
||||
s += "\n" + Ordergroup.human_attribute_name(:contact) + ': ' + ordergroup.contact_person if ordergroup.contact_person.present?
|
||||
s
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,7 +4,7 @@ module ApplicationHelper
|
|||
include PathHelper
|
||||
|
||||
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
|
||||
|
||||
def format_date(time = Time.now)
|
||||
|
@ -16,7 +16,7 @@ module ApplicationHelper
|
|||
end
|
||||
|
||||
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
|
||||
|
||||
def format_currency(amount)
|
||||
|
@ -26,28 +26,28 @@ module ApplicationHelper
|
|||
|
||||
# Splits an IBAN into groups of 4 digits displayed with margins in between
|
||||
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
|
||||
|
||||
# Creates ajax-controlled-links for pagination
|
||||
def pagination_links_remote(collection, options = {})
|
||||
per_page = options[:per_page] || @per_page
|
||||
params = options[:params] || {}
|
||||
params = params.merge({ :per_page => per_page })
|
||||
paginate collection, :params => params, :remote => true
|
||||
params = params.merge({ per_page: per_page })
|
||||
paginate collection, params: params, remote: true
|
||||
end
|
||||
|
||||
# Link-collection for per_page-options when using the pagination-plugin
|
||||
def items_per_page(options = {})
|
||||
per_page_options = options[:per_page_options] || [20, 50, 100, 500]
|
||||
current = options[:current] || @per_page
|
||||
params = params || {}
|
||||
params ||= {}
|
||||
|
||||
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 << ' 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
|
||||
|
||||
if options[:wrap] == false
|
||||
|
@ -63,21 +63,19 @@ module ApplicationHelper
|
|||
# Hmtl options
|
||||
remote = options[:remote].nil? ? true : options[:remote]
|
||||
class_name = case params[:sort]
|
||||
when key then
|
||||
when key
|
||||
'sortup'
|
||||
when key + '_reverse' then
|
||||
when key + '_reverse'
|
||||
'sortdown'
|
||||
else
|
||||
nil
|
||||
end
|
||||
html_options = {
|
||||
:title => I18n.t('helpers.application.sort_by', text: text),
|
||||
:remote => remote,
|
||||
:class => class_name
|
||||
title: I18n.t('helpers.application.sort_by', text: text),
|
||||
remote: remote,
|
||||
class: class_name
|
||||
}
|
||||
|
||||
# Url options
|
||||
key += "_reverse" if params[:sort] == key
|
||||
key += '_reverse' if params[:sort] == key
|
||||
per_page = options[:per_page] || @per_page
|
||||
url_options = params.merge(per_page: per_page, sort: key)
|
||||
url_options.merge!({ page: params[:page] }) if params[:page]
|
||||
|
@ -95,14 +93,16 @@ module ApplicationHelper
|
|||
# be overridden by the option 'desc'.
|
||||
# Other options are passed through to I18n.
|
||||
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)
|
||||
if options[:short]
|
||||
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
|
||||
sshort = model.human_attribute_name("#{attribute}_short".to_sym, options.merge({ fallback: true, default: '', count: 2 }))
|
||||
s = raw "<abbr title='#{desc}'>#{sshort}</abbr>" unless sshort.blank?
|
||||
sshort = model.human_attribute_name("#{attribute}_short".to_sym,
|
||||
options.merge({ fallback: true, default: '', count: 2 }))
|
||||
s = raw "<abbr title='#{desc}'>#{sshort}</abbr>" if sshort.present?
|
||||
end
|
||||
s
|
||||
end
|
||||
|
@ -117,7 +117,7 @@ module ApplicationHelper
|
|||
# Returns the weekday. 0 is sunday, 1 is monday and so on
|
||||
def weekday(dayNumber)
|
||||
weekdays = I18n.t('date.day_names')
|
||||
return weekdays[dayNumber]
|
||||
weekdays[dayNumber]
|
||||
end
|
||||
|
||||
# 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 = {})
|
||||
icons = {
|
||||
:delete => { :file => 'b_drop.png', :alt => I18n.t('ui.delete') },
|
||||
:edit => { :file => 'b_edit.png', :alt => I18n.t('ui.edit') },
|
||||
:members => { :file => 'b_users.png', :alt => I18n.t('helpers.application.edit_user') }
|
||||
delete: { file: 'b_drop.png', alt: I18n.t('ui.delete') },
|
||||
edit: { file: 'b_edit.png', alt: I18n.t('ui.edit') },
|
||||
members: { file: 'b_users.png', alt: I18n.t('helpers.application.edit_user') }
|
||||
}
|
||||
options[:alt] ||= icons[name][:alt]
|
||||
options[:title] ||= icons[name][:title]
|
||||
options.merge!({ :size => '16x16', :border => "0" })
|
||||
options.merge!({ size: '16x16', border: '0' })
|
||||
|
||||
image_tag icons[name][:file], options
|
||||
end
|
||||
|
@ -150,27 +150,29 @@ module ApplicationHelper
|
|||
# Remote links with default 'loader'.gif during request
|
||||
def remote_link_to(text, options = {})
|
||||
remote_options = {
|
||||
:before => "Element.show('loader')",
|
||||
:success => "Element.hide('loader')",
|
||||
:method => :get
|
||||
before: "Element.show('loader')",
|
||||
success: "Element.hide('loader')",
|
||||
method: :get
|
||||
}
|
||||
link_to(text, options[:url], remote_options.merge(options))
|
||||
end
|
||||
|
||||
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}?" }
|
||||
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
|
||||
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
|
||||
roles.map { |r| names[r] }.join(', ')
|
||||
end
|
||||
end
|
||||
|
||||
def link_to_gmaps(address)
|
||||
link_to h(address), "http://maps.google.com/?q=#{h(address)}", :title => I18n.t('helpers.application.show_google_maps'),
|
||||
:target => "_blank"
|
||||
link_to h(address), "http://maps.google.com/?q=#{h(address)}", title: I18n.t('helpers.application.show_google_maps'),
|
||||
target: '_blank', rel: 'noopener'
|
||||
end
|
||||
|
||||
# Returns flash messages html.
|
||||
|
@ -186,8 +188,8 @@ module ApplicationHelper
|
|||
type = :success if type == 'notice'
|
||||
type = :error if type == 'alert'
|
||||
text = content_tag(:div,
|
||||
content_tag(:button, I18n.t('ui.marks.close').html_safe, :class => "close", "data-dismiss" => "alert") +
|
||||
message, :class => "alert fade in alert-#{type}")
|
||||
content_tag(:button, I18n.t('ui.marks.close').html_safe, :class => 'close', 'data-dismiss' => 'alert') +
|
||||
message, class: "alert fade in alert-#{type}")
|
||||
flash_messages << text if message
|
||||
end
|
||||
flash_messages.join("\n").html_safe
|
||||
|
@ -195,17 +197,17 @@ module ApplicationHelper
|
|||
|
||||
# render base errors in a form after failed validation
|
||||
# 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?
|
||||
|
||||
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
|
||||
|
||||
# show a user, depending on settings
|
||||
def show_user(user = @current_user, options = {})
|
||||
if user.nil?
|
||||
"?"
|
||||
'?'
|
||||
elsif FoodsoftConfig[:use_nick]
|
||||
if options[:full] && options[:markup]
|
||||
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
|
||||
end
|
||||
else
|
||||
"#{user.first_name} #{user.last_name}" + (options[:unique] ? " (\##{user.id})" : '')
|
||||
"#{user.first_name} #{user.last_name}" + (options[:unique] ? " (##{user.id})" : '')
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -258,9 +260,9 @@ module ApplicationHelper
|
|||
|
||||
# @return [String] stylesheet tag for foodcoop CSS style (+custom_css+ foodcoop config)
|
||||
# @see #foodcoop_css_path
|
||||
def foodcoop_css_tag(options = {})
|
||||
unless FoodsoftConfig[:custom_css].blank?
|
||||
def foodcoop_css_tag(_options = {})
|
||||
return if FoodsoftConfig[:custom_css].blank?
|
||||
|
||||
stylesheet_link_tag foodcoop_css_path, media: 'all'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,13 +3,13 @@ module ArticlesHelper
|
|||
def highlight_new(unequal_attributes, attribute)
|
||||
return unless unequal_attributes
|
||||
|
||||
unequal_attributes.has_key?(attribute) ? "background-color: yellow" : ""
|
||||
unequal_attributes.has_key?(attribute) ? 'background-color: yellow' : ''
|
||||
end
|
||||
|
||||
def row_classes(article)
|
||||
classes = []
|
||||
classes << "unavailable" if !article.availability
|
||||
classes << "just-updated" if article.recently_updated && article.availability
|
||||
classes.join(" ")
|
||||
classes << 'unavailable' unless article.availability
|
||||
classes << 'just-updated' if article.recently_updated && article.availability
|
||||
classes.join(' ')
|
||||
end
|
||||
end
|
||||
|
|
|
@ -11,11 +11,11 @@ module DeliveriesHelper
|
|||
|
||||
def articles_for_select2(articles, except = [], &block)
|
||||
articles = articles.reorder('articles.name ASC')
|
||||
articles = articles.reject { |a| not except.index(a.id).nil? } if except
|
||||
block_given? or block = Proc.new { |a| "#{a.name} (#{number_to_currency a.price}/#{a.unit})" }
|
||||
articles = articles.reject { |a| !except.index(a.id).nil? } if except
|
||||
block_given? or block = proc { |a| "#{a.name} (#{number_to_currency a.price}/#{a.unit})" }
|
||||
articles.map do |a|
|
||||
{ :id => a.id, :text => block.call(a) }
|
||||
end.unshift({ :id => '', :text => '' })
|
||||
{ id: a.id, text: block.call(a) }
|
||||
end.unshift({ id: '', text: '' })
|
||||
end
|
||||
|
||||
def articles_for_table(articles)
|
||||
|
@ -23,10 +23,14 @@ module DeliveriesHelper
|
|||
end
|
||||
|
||||
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 += link_to t('deliveries.stock_change_fields.remove_article'), "#", :class => 'destroy_stock_change btn btn-small'
|
||||
return output.html_safe
|
||||
output += link_to t('deliveries.stock_change_fields.remove_article'), '#',
|
||||
class: 'destroy_stock_change btn btn-small'
|
||||
output.html_safe
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,11 +2,11 @@ module Finance::BalancingHelper
|
|||
def balancing_view_partial
|
||||
view = params[:view] || 'edit_results'
|
||||
case view
|
||||
when 'edit_results' then
|
||||
when 'edit_results'
|
||||
'edit_results_by_articles'
|
||||
when 'groups_overview' then
|
||||
when 'groups_overview'
|
||||
'shared/articles_by/groups'
|
||||
when 'articles_overview' then
|
||||
when 'articles_overview'
|
||||
'shared/articles_by/articles'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
module Finance::InvoicesHelper
|
||||
def format_delivery_item delivery
|
||||
def format_delivery_item(delivery)
|
||||
format_date(delivery.date)
|
||||
end
|
||||
|
||||
def format_order_item order
|
||||
def format_order_item(order)
|
||||
"#{format_date(order.ends)} (#{number_to_currency(order.sum)})"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,12 +2,12 @@ module GroupOrderArticlesHelper
|
|||
# return an edit field for a GroupOrderArticle result
|
||||
def group_order_article_edit_result(goa)
|
||||
result = number_with_precision goa.result, strip_insignificant_zeros: true
|
||||
unless goa.group_order.order.finished? && current_user.role_finance?
|
||||
result
|
||||
else
|
||||
if goa.group_order.order.finished? && current_user.role_finance?
|
||||
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
|
||||
end
|
||||
else
|
||||
result
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
module GroupOrdersHelper
|
||||
def data_to_js(ordering_data)
|
||||
ordering_data[:order_articles].map { |id, data|
|
||||
[id, data[:price], data[:unit], data[:total_price], data[:others_quantity], data[:others_tolerance], data[:used_quantity], data[:quantity_available]]
|
||||
}.map { |row|
|
||||
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]]
|
||||
end.map do |row|
|
||||
"addData(#{row.join(', ')});"
|
||||
}.join("\n")
|
||||
end.join("\n")
|
||||
end
|
||||
|
||||
# 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
|
||||
group_order_path(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
|
||||
new_group_order_path(:order_id => order.id)
|
||||
new_group_order_path(order_id: order.id)
|
||||
end
|
||||
options.delete(:show)
|
||||
name = block_given? ? capture(&block) : order.name
|
||||
|
@ -26,7 +27,7 @@ module GroupOrdersHelper
|
|||
# Return css class names for order result table
|
||||
|
||||
def order_article_class_name(quantity, tolerance, result)
|
||||
if (quantity + tolerance > 0)
|
||||
if quantity + tolerance > 0
|
||||
result > 0 ? 'success' : 'failed'
|
||||
else
|
||||
'ignored'
|
||||
|
@ -45,12 +46,12 @@ module GroupOrdersHelper
|
|||
end
|
||||
|
||||
def get_missing_units_css_class(quantity_missing)
|
||||
if (quantity_missing == 1)
|
||||
return 'missing-few';
|
||||
elsif (quantity_missing == 0)
|
||||
return ''
|
||||
if quantity_missing == 1
|
||||
'missing-few'
|
||||
elsif quantity_missing == 0
|
||||
''
|
||||
else
|
||||
return 'missing-many'
|
||||
'missing-many'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
module OrderArticlesHelper
|
||||
def article_label_with_unit(article)
|
||||
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
|
||||
|
|
|
@ -18,7 +18,7 @@ module OrdersHelper
|
|||
|
||||
def options_for_suppliers_to_select
|
||||
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_for_select(options)
|
||||
end
|
||||
|
@ -29,14 +29,14 @@ module OrdersHelper
|
|||
nil
|
||||
else
|
||||
units_info = []
|
||||
[:units_to_order, :units_billed, :units_received].map do |unit|
|
||||
if n = order_article.send(unit)
|
||||
%i[units_to_order units_billed units_received].map do |unit|
|
||||
next unless n = order_article.send(unit)
|
||||
|
||||
line = n.to_s + ' '
|
||||
line += pkg_helper(order_article.price, options) + ' ' unless n == 0
|
||||
line += OrderArticle.human_attribute_name("#{unit}_short", count: n)
|
||||
units_info << line
|
||||
end
|
||||
end
|
||||
units_info.join(', ').html_safe
|
||||
end
|
||||
end
|
||||
|
@ -67,8 +67,8 @@ module OrdersHelper
|
|||
def pkg_helper_icon(c = nil, options = {})
|
||||
options = { tag: 'i', class: '' }.merge(options)
|
||||
if c.nil?
|
||||
c = " ".html_safe
|
||||
options[:class] += " icon-only"
|
||||
c = ' '.html_safe
|
||||
options[:class] += ' icon-only'
|
||||
end
|
||||
content_tag(options[:tag], c, class: "package #{options[:class]}").html_safe
|
||||
end
|
||||
|
@ -94,11 +94,12 @@ module OrdersHelper
|
|||
autocomplete: 'off'
|
||||
|
||||
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') {
|
||||
content_tag(:i, nil, class: 'icon icon-unlock')
|
||||
} + input_html
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
input_html.html_safe
|
||||
|
@ -109,18 +110,16 @@ module OrdersHelper
|
|||
def ordergroup_count(order)
|
||||
group_orders = order.group_orders.includes(:ordergroup)
|
||||
txt = "#{group_orders.count} #{Ordergroup.model_name.human count: group_orders.count}"
|
||||
if group_orders.count == 0
|
||||
return txt
|
||||
else
|
||||
return txt if group_orders.count == 0
|
||||
|
||||
desc = group_orders.includes(:ordergroup).map { |g| g.ordergroup_name }.join(', ')
|
||||
content_tag(:abbr, txt, title: desc).html_safe
|
||||
end
|
||||
end
|
||||
|
||||
# @param order_or_supplier [Order, Supplier] Order or supplier to link to
|
||||
# @return [String] Link to order or supplier, showing its name.
|
||||
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
|
||||
else
|
||||
link_to(@order.supplier.name, supplier_path(@order.supplier)).html_safe
|
||||
|
@ -152,7 +151,8 @@ module OrdersHelper
|
|||
if order.stockit?
|
||||
content_tag :div, t('orders.index.action_receive'), class: "btn disabled #{options[:class]}"
|
||||
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
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
module StockitHelper
|
||||
def stock_article_classes(article)
|
||||
class_names = []
|
||||
class_names << "unavailable" if article.quantity_available <= 0
|
||||
class_names.join(" ")
|
||||
class_names << 'unavailable' if article.quantity_available <= 0
|
||||
class_names.join(' ')
|
||||
end
|
||||
|
||||
def link_to_stock_change_reason(stock_change)
|
||||
|
@ -17,8 +17,8 @@ module StockitHelper
|
|||
|
||||
def stock_article_price_hint(stock_article)
|
||||
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),
|
||||
:remote => true))
|
||||
remote: true))
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
module TasksHelper
|
||||
def task_assignments(task)
|
||||
task.assignments.map do |ass|
|
||||
content_tag :span, show_user(ass.user), :class => (ass.accepted? ? 'accepted' : 'unaccepted')
|
||||
end.join(", ").html_safe
|
||||
content_tag :span, show_user(ass.user), class: (ass.accepted? ? 'accepted' : 'unaccepted')
|
||||
end.join(', ').html_safe
|
||||
end
|
||||
|
||||
# generate colored number of still required users
|
||||
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)
|
||||
end
|
||||
title: I18n.t('helpers.tasks.required_users', count: task.still_required_users)
|
||||
end
|
||||
|
||||
def task_title(task)
|
||||
|
|
|
@ -6,7 +6,7 @@ class DeltaInput < SimpleForm::Inputs::StringInput
|
|||
options[:data] ||= {}
|
||||
options[:data][:delta] ||= 1
|
||||
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
|
||||
delta_button(content_tag(:i, nil, class: 'icon icon-minus'), -1, options) +
|
||||
|
|
|
@ -29,7 +29,7 @@ class AppleBar
|
|||
|
||||
def mean_order_amount_per_job
|
||||
(1 / @global_avg).round
|
||||
rescue
|
||||
rescue StandardError
|
||||
0
|
||||
end
|
||||
|
||||
|
|
|
@ -41,14 +41,14 @@ class BankAccountConnector
|
|||
end
|
||||
end
|
||||
|
||||
@@registered_classes = Set.new
|
||||
@registered_classes = Set.new
|
||||
|
||||
def self.register(klass)
|
||||
@@registered_classes.add klass
|
||||
@registered_classes.add klass
|
||||
end
|
||||
|
||||
def self.find(iban)
|
||||
@@registered_classes.each do |klass|
|
||||
@registered_classes.each do |klass|
|
||||
return klass if klass.handles(iban)
|
||||
end
|
||||
nil
|
||||
|
|
|
@ -17,16 +17,16 @@ class BankAccountInformationImporter
|
|||
ret = 0
|
||||
booked.each do |t|
|
||||
amount = parse_account_information_amount t[:transactionAmount]
|
||||
entityName = amount < 0 ? t[:creditorName] : t[:debtorName]
|
||||
entityAccount = amount < 0 ? t[:creditorAccount] : t[:debtorAccount]
|
||||
entity_name = amount < 0 ? t[:creditorName] : t[:debtorName]
|
||||
entity_account = amount < 0 ? t[:creditorAccount] : t[:debtorAccount]
|
||||
reference = [t[:endToEndId], t[:remittanceInformationUnstructured]].join("\n").strip
|
||||
|
||||
@bank_account.bank_transactions.where(external_id: t[:transactionId]).first_or_create.update({
|
||||
date: t[:bookingDate],
|
||||
amount: amount,
|
||||
iban: entityAccount && entityAccount[:iban],
|
||||
iban: entity_account && entity_account[:iban],
|
||||
reference: reference,
|
||||
text: entityName,
|
||||
text: entity_name,
|
||||
receipt: t[:additionalInformation]
|
||||
})
|
||||
ret += 1
|
||||
|
@ -34,7 +34,7 @@ class BankAccountInformationImporter
|
|||
|
||||
balances = (data[:balances] ? data[:balances].map { |b| [b[:balanceType], b[:balanceAmount]] } : []).to_h
|
||||
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]
|
||||
if value
|
||||
balance = value
|
||||
|
|
|
@ -10,66 +10,68 @@ module DateTimeAttributeValidate
|
|||
super
|
||||
|
||||
attributes.each do |attribute|
|
||||
validate -> { self.send("#{attribute}_datetime_value_valid") }
|
||||
validate -> { send("#{attribute}_datetime_value_valid") }
|
||||
|
||||
# allow resetting the field to nil
|
||||
before_validation do
|
||||
if self.instance_variable_get("@#{attribute}_is_set")
|
||||
date = self.instance_variable_get("@#{attribute}_date_value")
|
||||
time = self.instance_variable_get("@#{attribute}_time_value")
|
||||
if date.blank? && time.blank?
|
||||
self.send("#{attribute}=", nil)
|
||||
end
|
||||
if instance_variable_get("@#{attribute}_is_set")
|
||||
date = instance_variable_get("@#{attribute}_date_value")
|
||||
time = instance_variable_get("@#{attribute}_time_value")
|
||||
send("#{attribute}=", nil) if date.blank? && time.blank?
|
||||
end
|
||||
end
|
||||
|
||||
# remember old date and time values
|
||||
define_method("#{attribute}_date_value=") do |val|
|
||||
self.instance_variable_set("@#{attribute}_is_set", true)
|
||||
self.instance_variable_set("@#{attribute}_date_value", val)
|
||||
instance_variable_set("@#{attribute}_is_set", true)
|
||||
instance_variable_set("@#{attribute}_date_value", val)
|
||||
begin
|
||||
self.send("#{attribute}_date=", val)
|
||||
rescue
|
||||
send("#{attribute}_date=", val)
|
||||
rescue StandardError
|
||||
nil
|
||||
end
|
||||
end
|
||||
define_method("#{attribute}_time_value=") do |val|
|
||||
self.instance_variable_set("@#{attribute}_is_set", true)
|
||||
self.instance_variable_set("@#{attribute}_time_value", val)
|
||||
instance_variable_set("@#{attribute}_is_set", true)
|
||||
instance_variable_set("@#{attribute}_time_value", val)
|
||||
begin
|
||||
self.send("#{attribute}_time=", val)
|
||||
rescue
|
||||
send("#{attribute}_time=", val)
|
||||
rescue StandardError
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
# fallback to field when values are not set
|
||||
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
|
||||
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
|
||||
|
||||
private
|
||||
|
||||
# validate date and time
|
||||
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
|
||||
Date.parse(date)
|
||||
rescue
|
||||
rescue StandardError
|
||||
nil
|
||||
end
|
||||
errors.add(attribute, "is not a valid date") # @todo I18n
|
||||
errors.add(attribute, 'is not a valid date') # @todo I18n
|
||||
end
|
||||
time = self.instance_variable_get("@#{attribute}_time_value")
|
||||
time = instance_variable_get("@#{attribute}_time_value")
|
||||
unless time.blank? || begin
|
||||
Time.parse(time)
|
||||
rescue
|
||||
rescue StandardError
|
||||
nil
|
||||
end
|
||||
errors.add(attribute, "is not a valid time") # @todo I18n
|
||||
errors.add(attribute, 'is not a valid time') # @todo I18n
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -14,7 +14,7 @@ module Foodsoft
|
|||
cattr_accessor :variables
|
||||
|
||||
# Hash of variables. Note that keys are Strings.
|
||||
@@variables = {
|
||||
@variables = {
|
||||
'scope' => -> { FoodsoftConfig.scope },
|
||||
'name' => -> { FoodsoftConfig[:name] },
|
||||
'contact.street' => -> { FoodsoftConfig[:contact][:street] },
|
||||
|
@ -39,13 +39,13 @@ module Foodsoft
|
|||
'supplier_count' => -> { Supplier.undeleted.count },
|
||||
'active_supplier_count' => -> { active_supplier_count },
|
||||
'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 [String] Expanded variable
|
||||
def self.get(var)
|
||||
s = @@variables[var.to_s]
|
||||
s = @variables[var.to_s]
|
||||
s.respond_to?(:call) ? s.call : s.to_s
|
||||
end
|
||||
|
||||
|
@ -55,7 +55,7 @@ module Foodsoft
|
|||
# @return [String] Expanded string
|
||||
def self.expand(str, options = {})
|
||||
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
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ class FoodsoftConfig
|
|||
# Load initial config from development or production
|
||||
set_config Rails.env
|
||||
# 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_missing
|
||||
# Make sure relevant configuration is applied, also in single coops mode,
|
||||
|
@ -79,7 +79,7 @@ class FoodsoftConfig
|
|||
end
|
||||
|
||||
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]
|
||||
end
|
||||
end
|
||||
|
@ -117,7 +117,7 @@ class FoodsoftConfig
|
|||
# @return [Object] Value of the key.
|
||||
def [](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
|
||||
else
|
||||
|
@ -139,20 +139,20 @@ class FoodsoftConfig
|
|||
if config[key] == value || (config[key].nil? && value == false)
|
||||
# delete (ok if it was already deleted)
|
||||
begin
|
||||
RailsSettings::CachedSettings.destroy "foodcoop.#{self.scope}.#{key}"
|
||||
RailsSettings::CachedSettings.destroy "foodcoop.#{scope}.#{key}"
|
||||
rescue RailsSettings::Settings::SettingNotFound
|
||||
end
|
||||
else
|
||||
# or store
|
||||
RailsSettings::CachedSettings["foodcoop.#{self.scope}.#{key}"] = value
|
||||
RailsSettings::CachedSettings["foodcoop.#{scope}.#{key}"] = value
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
# @return [Array<String>] Configuration keys that are set (either in +app_config.yml+ or database).
|
||||
def keys
|
||||
keys = RailsSettings::CachedSettings.get_all("foodcoop.#{self.scope}.").try(:keys) || []
|
||||
keys.map! { |k| k.gsub(/^foodcoop\.#{self.scope}\./, '') }
|
||||
keys = RailsSettings::CachedSettings.get_all("foodcoop.#{scope}.").try(:keys) || []
|
||||
keys.map! { |k| k.gsub(/^foodcoop\.#{scope}\./, '') }
|
||||
keys += config.keys
|
||||
keys.map(&:to_s).uniq
|
||||
end
|
||||
|
@ -181,10 +181,10 @@ class FoodsoftConfig
|
|||
# @return [Boolean] Whether this key may be set in the database
|
||||
def allowed_key?(key)
|
||||
# fast check for keys without nesting
|
||||
if self.config[:protected].include? key
|
||||
!self.config[:protected][key]
|
||||
if config[:protected].include? key
|
||||
!config[:protected][key]
|
||||
else
|
||||
!self.config[:protected][:all]
|
||||
!config[:protected][:all]
|
||||
end
|
||||
# @todo allow to check nested keys as well
|
||||
end
|
||||
|
@ -287,7 +287,9 @@ class FoodsoftConfig
|
|||
def normalize_value(value)
|
||||
value = value.map { |v| normalize_value(v) } if value.is_a? Array
|
||||
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
|
||||
case value
|
||||
when 'true' then true
|
||||
|
|
|
@ -8,26 +8,24 @@ module FoodsoftDateUtil
|
|||
# @todo handle ical parse errors
|
||||
occ = begin
|
||||
schedule.next_occurrence(from).to_time
|
||||
rescue
|
||||
rescue StandardError
|
||||
nil
|
||||
end
|
||||
end
|
||||
if options && options[:time] && occ
|
||||
occ = occ.beginning_of_day.advance(seconds: Time.parse(options[:time]).seconds_since_midnight)
|
||||
end
|
||||
occ = occ.beginning_of_day.advance(seconds: Time.parse(options[:time]).seconds_since_midnight) if options && options[:time] && occ
|
||||
occ
|
||||
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
|
||||
def self.rule_from(p)
|
||||
case p
|
||||
def self.rule_from(rule)
|
||||
case rule
|
||||
when String
|
||||
IceCube::Rule.from_ical(p)
|
||||
IceCube::Rule.from_ical(rule)
|
||||
when Hash
|
||||
IceCube::Rule.from_hash(p)
|
||||
IceCube::Rule.from_hash(rule)
|
||||
else
|
||||
p
|
||||
rule
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,17 +7,17 @@ class FoodsoftFile
|
|||
SpreadsheetFile.parse file, options do |row, row_index|
|
||||
next if row[2].blank?
|
||||
|
||||
article = { :order_number => row[1],
|
||||
:name => row[2],
|
||||
:note => row[3],
|
||||
:manufacturer => row[4],
|
||||
:origin => row[5],
|
||||
:unit => row[6],
|
||||
:price => row[7],
|
||||
:tax => row[8],
|
||||
:deposit => (row[9].nil? ? "0" : row[9]),
|
||||
:unit_quantity => row[10],
|
||||
:article_category => row[13] }
|
||||
article = { order_number: row[1],
|
||||
name: row[2],
|
||||
note: row[3],
|
||||
manufacturer: row[4],
|
||||
origin: row[5],
|
||||
unit: row[6],
|
||||
price: row[7],
|
||||
tax: row[8],
|
||||
deposit: (row[9].nil? ? '0' : row[9]),
|
||||
unit_quantity: row[10],
|
||||
article_category: row[13] }
|
||||
status = row[0] && row[0].strip.downcase == 'x' ? :outlisted : nil
|
||||
yield status, article, row_index
|
||||
end
|
||||
|
|
|
@ -23,8 +23,8 @@ class FoodsoftMailReceiver < MidiSmtpServer::Smtpd
|
|||
recipient = rcpt_to.gsub(/^\s*<\s*(.*)\s*>\s*$/, '\1')
|
||||
@handlers << self.class.find_handler(recipient)
|
||||
rcpt_to
|
||||
rescue => error
|
||||
logger.info("Can not accept mail for '#{rcpt_to}': #{error}")
|
||||
rescue StandardError => e
|
||||
logger.info("Can not accept mail for '#{rcpt_to}': #{e}")
|
||||
raise MidiSmtpServer::Smtpd550Exception
|
||||
end
|
||||
|
||||
|
@ -32,16 +32,16 @@ class FoodsoftMailReceiver < MidiSmtpServer::Smtpd
|
|||
@handlers.each do |handler|
|
||||
handler.call(ctx[:message][:data])
|
||||
end
|
||||
rescue => error
|
||||
ExceptionNotifier.notify_exception(error, data: ctx)
|
||||
raise error
|
||||
rescue StandardError => e
|
||||
ExceptionNotifier.notify_exception(e, data: ctx)
|
||||
raise e
|
||||
ensure
|
||||
@handlers.clear
|
||||
end
|
||||
|
||||
def self.find_handler(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]
|
||||
|
||||
FoodsoftConfig.select_multifoodcoop m[:foodcoop]
|
||||
|
@ -53,6 +53,6 @@ class FoodsoftMailReceiver < MidiSmtpServer::Smtpd
|
|||
end
|
||||
end
|
||||
|
||||
raise "invalid format for recipient"
|
||||
raise 'invalid format for recipient'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -14,7 +14,7 @@ class OrderCsv < RenderCsv
|
|||
end
|
||||
|
||||
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 [
|
||||
oa.units_to_order,
|
||||
oa.article.order_number,
|
||||
|
|
|
@ -55,7 +55,7 @@ class OrderPdf < RenderPdf
|
|||
end
|
||||
|
||||
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
|
||||
|
||||
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)')
|
||||
|
||||
result.map do |item|
|
||||
[item.first || stock_ordergroup_name] + item[1..-1]
|
||||
[item.first || stock_ordergroup_name] + item[1..]
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -103,7 +103,7 @@ class OrderPdf < RenderPdf
|
|||
def each_ordergroup_batch(batch_size)
|
||||
offset = 0
|
||||
|
||||
while true
|
||||
loop do
|
||||
go_records = ordergroups(offset, batch_size)
|
||||
|
||||
break unless go_records.any?
|
||||
|
@ -136,7 +136,7 @@ class OrderPdf < RenderPdf
|
|||
group_order_articles(ordergroup)
|
||||
.includes(order_article: { article: [:supplier] })
|
||||
.order('suppliers.name, articles.name')
|
||||
.preload(order_article: [:article_price, :order])
|
||||
.preload(order_article: %i[article_price order])
|
||||
.each(&block)
|
||||
end
|
||||
|
||||
|
|
|
@ -8,23 +8,19 @@ class OrderTxt
|
|||
def to_txt
|
||||
supplier = @order.supplier
|
||||
contact = FoodsoftConfig[:contact].symbolize_keys
|
||||
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 = I18n.t('orders.fax.heading', name: FoodsoftConfig[:name])
|
||||
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\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 += "****** " + 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 += '****** ' + 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'))
|
||||
# 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)
|
||||
end
|
||||
text
|
||||
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
|
||||
|
|
|
@ -13,7 +13,7 @@ class RenderCsv
|
|||
end
|
||||
|
||||
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|
|
||||
if h = header
|
||||
csv << h
|
||||
|
@ -31,12 +31,6 @@ class RenderCsv
|
|||
yield []
|
||||
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.
|
||||
def number_to_currency(number, options = {})
|
||||
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 }
|
||||
end
|
||||
|
||||
def draw_borders(pt)
|
||||
def draw_borders(point)
|
||||
@pdf.mask(:line_width, :stroke_color) do
|
||||
x, y = pt
|
||||
x, y = point
|
||||
from = [[x - skew, y + (border_top_width / 2.0)],
|
||||
to = [x, y - height - (border_bottom_width / 2.0)]]
|
||||
|
||||
|
@ -118,11 +118,6 @@ class RenderPdf < Prawn::Document
|
|||
render # Render pdf
|
||||
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 :/
|
||||
def number_to_currency(number, options = {})
|
||||
super(number, options).gsub("\u202f", ' ') if number
|
||||
|
@ -148,8 +143,8 @@ class RenderPdf < Prawn::Document
|
|||
|
||||
protected
|
||||
|
||||
def fontsize(n)
|
||||
n
|
||||
def fontsize(size)
|
||||
size
|
||||
end
|
||||
|
||||
# return whether pagebreak or vertical whitespace is used for breaks
|
||||
|
|
|
@ -19,10 +19,10 @@ class TokenVerifier < ActiveSupport::MessageVerifier
|
|||
raise InvalidPrefix unless r[1] == @_prefix
|
||||
|
||||
# return original message
|
||||
if r.length > 2
|
||||
return unless r.length > 2
|
||||
|
||||
r[2]
|
||||
end
|
||||
end
|
||||
|
||||
class InvalidMessage < ActiveSupport::MessageVerifier::InvalidSignature; end
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ class Mailer < ActionMailer::Base
|
|||
|
||||
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
|
||||
|
||||
mail to: order.supplier.email,
|
||||
|
@ -122,10 +122,11 @@ class Mailer < ActionMailer::Base
|
|||
|
||||
if args[:from].is_a? User
|
||||
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
|
||||
|
||||
[:bcc, :cc, :reply_to, :sender, :to].each do |k|
|
||||
%i[bcc cc reply_to sender to].each do |k|
|
||||
user = args[k]
|
||||
args[k] = format_address(user.email, show_user(user)) if user.is_a? User
|
||||
end
|
||||
|
@ -145,21 +146,21 @@ class Mailer < ActionMailer::Base
|
|||
|
||||
def self.deliver_now_with_user_locale(user, &block)
|
||||
I18n.with_locale(user.settings['profile']['language']) do
|
||||
self.deliver_now(&block)
|
||||
deliver_now(&block)
|
||||
end
|
||||
end
|
||||
|
||||
def self.deliver_now_with_default_locale(&block)
|
||||
I18n.with_locale(FoodsoftConfig[:default_locale]) do
|
||||
self.deliver_now(&block)
|
||||
deliver_now(&block)
|
||||
end
|
||||
end
|
||||
|
||||
def self.deliver_now
|
||||
message = yield
|
||||
message.deliver_now
|
||||
rescue => error
|
||||
MailDeliveryStatus.create email: message.to[0], message: error.message
|
||||
rescue StandardError => e
|
||||
MailDeliveryStatus.create email: message.to[0], message: e.message
|
||||
end
|
||||
|
||||
# separate method to allow plugins to mess with the attachments
|
||||
|
@ -169,8 +170,7 @@ class Mailer < ActionMailer::Base
|
|||
end
|
||||
|
||||
# separate method to allow plugins to mess with the text
|
||||
def additonal_welcome_text(user)
|
||||
end
|
||||
def additonal_welcome_text(user); end
|
||||
|
||||
private
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ class Article < ApplicationRecord
|
|||
belongs_to :supplier
|
||||
# @!attribute article_prices
|
||||
# @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
|
||||
# @return [Array<OrderArticle>] Order articles for this article.
|
||||
has_many :order_articles
|
||||
|
@ -60,16 +60,16 @@ class Article < ApplicationRecord
|
|||
scope :not_in_stock, -> { where(type: nil) }
|
||||
|
||||
# Validations
|
||||
validates_presence_of :name, :unit, :price, :tax, :deposit, :unit_quantity, :supplier_id, :article_category
|
||||
validates_length_of :name, :in => 4..60
|
||||
validates_length_of :unit, :in => 1..15
|
||||
validates_length_of :note, :maximum => 255
|
||||
validates_length_of :origin, :maximum => 255
|
||||
validates_length_of :manufacturer, :maximum => 255
|
||||
validates_length_of :order_number, :maximum => 255
|
||||
validates_numericality_of :price, :greater_than_or_equal_to => 0
|
||||
validates_numericality_of :unit_quantity, :greater_than => 0
|
||||
validates_numericality_of :deposit, :tax
|
||||
validates :name, :unit, :price, :tax, :deposit, :unit_quantity, :supplier_id, :article_category, presence: true
|
||||
validates :name, length: { in: 4..60 }
|
||||
validates :unit, length: { in: 1..15 }
|
||||
validates :note, length: { maximum: 255 }
|
||||
validates :origin, length: { maximum: 255 }
|
||||
validates :manufacturer, length: { maximum: 255 }
|
||||
validates :order_number, length: { maximum: 255 }
|
||||
validates :price, numericality: { greater_than_or_equal_to: 0 }
|
||||
validates :unit_quantity, numericality: { greater_than: 0 }
|
||||
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, :unit, :unit_quantity]
|
||||
validate :uniqueness_of_name
|
||||
|
@ -78,12 +78,12 @@ class Article < ApplicationRecord
|
|||
before_save :update_price_history
|
||||
before_destroy :check_article_in_use
|
||||
|
||||
def self.ransackable_attributes(auth_object = nil)
|
||||
%w(id name supplier_id article_category_id unit note manufacturer origin unit_quantity order_number)
|
||||
def self.ransackable_attributes(_auth_object = nil)
|
||||
%w[id name supplier_id article_category_id unit note manufacturer origin unit_quantity order_number]
|
||||
end
|
||||
|
||||
def self.ransackable_associations(auth_object = nil)
|
||||
%w(article_category supplier order_articles orders)
|
||||
def self.ransackable_associations(_auth_object = nil)
|
||||
%w[article_category supplier order_articles orders]
|
||||
end
|
||||
|
||||
# Returns true if article has been updated at least 2 days ago
|
||||
|
@ -96,7 +96,7 @@ class Article < ApplicationRecord
|
|||
@in_open_order ||= begin
|
||||
order_articles = OrderArticle.where(order_id: Order.open.collect(&:id))
|
||||
order_article = order_articles.detect { |oa| oa.article_id == id }
|
||||
order_article ? order_article.order : nil
|
||||
order_article&.order
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -112,17 +112,17 @@ class Article < ApplicationRecord
|
|||
def shared_article_changed?(supplier = self.supplier)
|
||||
# skip early if the timestamp hasn't changed
|
||||
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?
|
||||
# when attributes not changed, update timestamp of article
|
||||
self.update_attribute(:shared_updated_on, shared_article.updated_on)
|
||||
update_attribute(:shared_updated_on, shared_article.updated_on)
|
||||
false
|
||||
else
|
||||
attrs
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Return article attributes that were changed (incl. unit conversion)
|
||||
# @param new_article [Article] New article to update self
|
||||
|
@ -131,30 +131,31 @@ class Article < ApplicationRecord
|
|||
def unequal_attributes(new_article, options = {})
|
||||
# try to convert different units when desired
|
||||
if options[:convert_units] == false
|
||||
new_price, new_unit_quantity = nil, nil
|
||||
new_price = nil
|
||||
new_unit_quantity = nil
|
||||
else
|
||||
new_price, new_unit_quantity = convert_units(new_article)
|
||||
end
|
||||
if new_price && new_unit_quantity
|
||||
new_unit = self.unit
|
||||
new_unit = unit
|
||||
else
|
||||
new_price = new_article.price
|
||||
new_unit_quantity = new_article.unit_quantity
|
||||
new_unit = new_article.unit
|
||||
end
|
||||
|
||||
return Article.compare_attributes(
|
||||
Article.compare_attributes(
|
||||
{
|
||||
:name => [self.name, new_article.name],
|
||||
:manufacturer => [self.manufacturer, new_article.manufacturer.to_s],
|
||||
:origin => [self.origin, new_article.origin],
|
||||
:unit => [self.unit, new_unit],
|
||||
:price => [self.price.to_f.round(2), new_price.to_f.round(2)],
|
||||
:tax => [self.tax, new_article.tax],
|
||||
:deposit => [self.deposit.to_f.round(2), new_article.deposit.to_f.round(2)],
|
||||
name: [name, new_article.name],
|
||||
manufacturer: [manufacturer, new_article.manufacturer.to_s],
|
||||
origin: [origin, new_article.origin],
|
||||
unit: [unit, new_unit],
|
||||
price: [price.to_f.round(2), new_price.to_f.round(2)],
|
||||
tax: [tax, new_article.tax],
|
||||
deposit: [deposit.to_f.round(2), new_article.deposit.to_f.round(2)],
|
||||
# take care of different num-objects.
|
||||
:unit_quantity => [self.unit_quantity.to_s.to_f, new_unit_quantity.to_s.to_f],
|
||||
:note => [self.note.to_s, new_article.note.to_s]
|
||||
unit_quantity: [unit_quantity.to_s.to_f, new_unit_quantity.to_s.to_f],
|
||||
note: [note.to_s, new_article.note.to_s]
|
||||
}
|
||||
)
|
||||
end
|
||||
|
@ -165,14 +166,20 @@ class Article < ApplicationRecord
|
|||
# @param attributes [Hash<Symbol, Array>] Attributes with old and new values
|
||||
# @return [Hash<Symbol, Object>] Changed attributes with new values
|
||||
def self.compare_attributes(attributes)
|
||||
unequal_attributes = attributes.select { |name, values| values[0] != values[1] && !(values[0].blank? && values[1].blank?) }
|
||||
Hash[unequal_attributes.to_a.map { |a| [a[0], a[1].last] }]
|
||||
unequal_attributes = attributes.select do |_name, values|
|
||||
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
|
||||
|
||||
# to get the correspondent shared article
|
||||
def shared_article(supplier = self.supplier)
|
||||
self.order_number.blank? and return nil
|
||||
@shared_article ||= supplier.shared_supplier.find_article_by_number(self.order_number) rescue nil
|
||||
order_number.blank? and return nil
|
||||
@shared_article ||= begin
|
||||
supplier.shared_supplier.find_article_by_number(order_number)
|
||||
rescue StandardError
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
# convert units in foodcoop-size
|
||||
|
@ -181,9 +188,10 @@ class Article < ApplicationRecord
|
|||
# returns false if units aren't foodsoft-compatible
|
||||
# returns nil if units are eqal
|
||||
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
|
||||
if new_article.unit == 'KI' && unit == 'ST' # 'KI' means a box, with a different amount of items in it
|
||||
# try to match the size out of its name, e.g. "banana 10-12 St" => 10
|
||||
new_unit_quantity = /[0-9\-\s]+(St)/.match(new_article.name).to_s.to_i
|
||||
if new_unit_quantity && new_unit_quantity > 0
|
||||
|
@ -193,8 +201,16 @@ class Article < ApplicationRecord
|
|||
false
|
||||
end
|
||||
else # use ruby-units to convert
|
||||
fc_unit = (::Unit.new(unit) rescue nil)
|
||||
supplier_unit = (::Unit.new(new_article.unit) rescue nil)
|
||||
fc_unit = begin
|
||||
::Unit.new(unit)
|
||||
rescue StandardError
|
||||
nil
|
||||
end
|
||||
supplier_unit = begin
|
||||
::Unit.new(new_article.unit)
|
||||
rescue StandardError
|
||||
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
|
||||
|
@ -204,9 +220,6 @@ class Article < ApplicationRecord
|
|||
false
|
||||
end
|
||||
end
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def deleted?
|
||||
|
@ -222,20 +235,20 @@ class Article < ApplicationRecord
|
|||
|
||||
# Checks if the article is in use before it will deleted
|
||||
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
|
||||
|
||||
# Create an ArticlePrice, when the price-attr are changed.
|
||||
def update_price_history
|
||||
if price_changed?
|
||||
return unless price_changed?
|
||||
|
||||
article_prices.build(
|
||||
:price => price,
|
||||
:tax => tax,
|
||||
:deposit => deposit,
|
||||
:unit_quantity => unit_quantity
|
||||
price: price,
|
||||
tax: tax,
|
||||
deposit: deposit,
|
||||
unit_quantity: unit_quantity
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def price_changed?
|
||||
changed.detect { |attr| attr == 'price' || 'tax' || 'deposit' || 'unit_quantity' } ? true : false
|
||||
|
@ -250,8 +263,8 @@ class Article < ApplicationRecord
|
|||
# supplier should always be there - except, perhaps, on initialization (on seeding)
|
||||
if supplier && (supplier.shared_sync_method.blank? || supplier.shared_sync_method == 'import')
|
||||
errors.add :name, :taken if matches.any?
|
||||
else
|
||||
errors.add :name, :taken_with_unit if matches.where(unit: unit, unit_quantity: unit_quantity).any?
|
||||
elsif matches.where(unit: unit, unit_quantity: unit_quantity).any?
|
||||
errors.add :name, :taken_with_unit
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -17,16 +17,16 @@ class ArticleCategory < ApplicationRecord
|
|||
|
||||
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
|
||||
|
||||
def self.ransackable_attributes(auth_object = nil)
|
||||
%w(id name)
|
||||
def self.ransackable_attributes(_auth_object = nil)
|
||||
%w[id name]
|
||||
end
|
||||
|
||||
def self.ransackable_associations(auth_object = nil)
|
||||
%w(articles order_articles orders)
|
||||
def self.ransackable_associations(_auth_object = nil)
|
||||
%w[articles order_articles orders]
|
||||
end
|
||||
|
||||
# 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)
|
||||
c = ArticleCategory.where('name LIKE ?', "%#{category}%") unless c && c.any?
|
||||
# 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
|
||||
c = c.sort_by { |s| s.name.length }.first if c.respond_to? :sort_by
|
||||
c
|
||||
|
@ -50,6 +54,9 @@ class ArticleCategory < ApplicationRecord
|
|||
|
||||
# Deny deleting the category when there are 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
|
||||
|
|
|
@ -24,8 +24,8 @@ class ArticlePrice < ApplicationRecord
|
|||
|
||||
localize_input_of :price, :tax, :deposit
|
||||
|
||||
validates_presence_of :price, :tax, :deposit, :unit_quantity
|
||||
validates_numericality_of :price, :greater_than_or_equal_to => 0
|
||||
validates_numericality_of :unit_quantity, :greater_than => 0
|
||||
validates_numericality_of :deposit, :tax
|
||||
validates :price, :tax, :deposit, :unit_quantity, presence: true
|
||||
validates :price, numericality: { greater_than_or_equal_to: 0 }
|
||||
validates :unit_quantity, numericality: { greater_than: 0 }
|
||||
validates :deposit, :tax, numericality: true
|
||||
end
|
||||
|
|
|
@ -5,10 +5,10 @@ class BankAccount < ApplicationRecord
|
|||
|
||||
normalize_attributes :name, :iban, :description
|
||||
|
||||
validates :name, :presence => true, :uniqueness => true, :length => { :minimum => 2 }
|
||||
validates :iban, :presence => true, :uniqueness => true
|
||||
validates_format_of :iban, :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 :name, presence: true, uniqueness: true, length: { minimum: 2 }
|
||||
validates :iban, presence: true, uniqueness: true
|
||||
validates :iban, format: { with: /\A[A-Z]{2}[0-9]{2}[0-9A-Z]{,30}\z/ }
|
||||
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
|
||||
def find_connector
|
||||
|
@ -18,10 +18,8 @@ class BankAccount < ApplicationRecord
|
|||
|
||||
def assign_unlinked_transactions
|
||||
count = 0
|
||||
bank_transactions.without_financial_link.includes(:supplier, :user).each do |t|
|
||||
if t.assign_to_ordergroup || t.assign_to_invoice
|
||||
count += 1
|
||||
end
|
||||
bank_transactions.without_financial_link.includes(:supplier, :user).find_each do |t|
|
||||
count += 1 if t.assign_to_ordergroup || t.assign_to_invoice
|
||||
end
|
||||
count
|
||||
end
|
||||
|
|
|
@ -4,5 +4,5 @@ class BankGateway < ApplicationRecord
|
|||
|
||||
scope :with_unattended_support, -> { where.not(unattended_user: nil) }
|
||||
|
||||
validates_presence_of :name, :url
|
||||
validates :name, :url, presence: true
|
||||
end
|
||||
|
|
|
@ -22,8 +22,8 @@ class BankTransaction < ApplicationRecord
|
|||
belongs_to :supplier, 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_numericality_of :amount
|
||||
validates :date, :amount, :bank_account_id, presence: true
|
||||
validates :amount, numericality: true
|
||||
|
||||
scope :without_financial_link, -> { where(financial_link: nil) }
|
||||
|
||||
|
@ -31,13 +31,13 @@ class BankTransaction < ApplicationRecord
|
|||
localize_input_of :amount
|
||||
|
||||
def image_url
|
||||
'data:image/png;base64,' + Base64.encode64(self.image)
|
||||
'data:image/png;base64,' + Base64.encode64(image)
|
||||
end
|
||||
|
||||
def assign_to_invoice
|
||||
return false unless supplier
|
||||
|
||||
content = text || ""
|
||||
content = text || ''
|
||||
content += "\n" + reference if reference.present?
|
||||
invoices = supplier.invoices.unpaid.select { |i| content.include? i.number }
|
||||
invoices_sum = invoices.map(&:amount).sum
|
||||
|
@ -49,7 +49,7 @@ class BankTransaction < ApplicationRecord
|
|||
update_attribute :financial_link, link
|
||||
end
|
||||
|
||||
return true
|
||||
true
|
||||
end
|
||||
|
||||
def assign_to_ordergroup
|
||||
|
@ -78,6 +78,6 @@ class BankTransaction < ApplicationRecord
|
|||
update_attribute :financial_link, link
|
||||
end
|
||||
|
||||
return true
|
||||
true
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,7 +10,7 @@ module CustomFields
|
|||
end
|
||||
|
||||
after_save do
|
||||
self.settings.custom_fields = custom_fields if custom_fields
|
||||
settings.custom_fields = custom_fields if custom_fields
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,9 +3,9 @@ module FindEachWithOrder
|
|||
extend ActiveSupport::Concern
|
||||
|
||||
class_methods do
|
||||
def find_each_with_order(options = {})
|
||||
def find_each_with_order(options = {}, &block)
|
||||
find_in_batches_with_order(options) do |records|
|
||||
records.each { |record| yield record }
|
||||
records.each(&block)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -5,12 +5,12 @@ module LocalizeInput
|
|||
return input unless input.is_a? String
|
||||
|
||||
Rails.logger.debug { "Input: #{input.inspect}" }
|
||||
separator = I18n.t("separator", 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!(separator, ".") # Replace separator with db compatible character
|
||||
separator = I18n.t('separator', 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!(separator, '.') # Replace separator with db compatible character
|
||||
input
|
||||
rescue
|
||||
rescue StandardError
|
||||
Rails.logger.warn "Can't localize input: #{input}"
|
||||
input
|
||||
end
|
||||
|
|
|
@ -3,7 +3,7 @@ module MarkAsDeletedWithName
|
|||
|
||||
def mark_as_deleted
|
||||
# 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) }
|
||||
max_length = lenval.options[:maximum]
|
||||
end
|
||||
|
|
|
@ -15,6 +15,6 @@ module PriceCalculation
|
|||
private
|
||||
|
||||
def add_percent(value, percent)
|
||||
(value * (percent * 0.01 + 1)).round(2)
|
||||
(value * ((percent * 0.01) + 1)).round(2)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,10 +4,10 @@ class Delivery < StockEvent
|
|||
|
||||
scope :recent, -> { order('created_at DESC').limit(10) }
|
||||
|
||||
validates_presence_of :supplier_id
|
||||
validates :supplier_id, presence: true
|
||||
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)
|
||||
for attributes in stock_change_attributes
|
||||
|
@ -16,7 +16,7 @@ class Delivery < StockEvent
|
|||
end
|
||||
|
||||
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
|
||||
|
||||
def sum(type = :gross)
|
||||
|
@ -39,8 +39,8 @@ class Delivery < StockEvent
|
|||
protected
|
||||
|
||||
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
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,13 +4,13 @@ class FinancialLink < ApplicationRecord
|
|||
has_many :invoices
|
||||
|
||||
scope :incomplete, -> { with_full_sum.where.not('full_sums.full_sum' => 0) }
|
||||
scope :unused, -> {
|
||||
scope :unused, lambda {
|
||||
includes(:bank_transactions, :financial_transactions, :invoices)
|
||||
.where(bank_transactions: { financial_link_id: nil })
|
||||
.where(financial_transactions: { 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)
|
||||
LEFT JOIN (
|
||||
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