Run rubocop --fix-layout and remove encoding comments
This commit is contained in:
parent
fa63e6e81d
commit
ea2862fdef
283 changed files with 1164 additions and 1969 deletions
|
|
@ -1,5 +1,6 @@
|
|||
module Api::Errors
|
||||
class Error < StandardError; end
|
||||
|
||||
# Authentication is handled by Doorkeeper, so no errors for that here
|
||||
class PermissionRequired < Error; end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
class AppleBar
|
||||
|
||||
attr_reader :ordergroup
|
||||
|
||||
def initialize(ordergroup)
|
||||
|
|
@ -17,7 +16,7 @@ class AppleBar
|
|||
'success'
|
||||
else
|
||||
if FoodsoftConfig[:stop_ordering_under].present? and
|
||||
apples >= FoodsoftConfig[:stop_ordering_under]
|
||||
apples >= FoodsoftConfig[:stop_ordering_under]
|
||||
'warning'
|
||||
else
|
||||
'danger'
|
||||
|
|
@ -31,7 +30,7 @@ class AppleBar
|
|||
end
|
||||
|
||||
def mean_order_amount_per_job
|
||||
(1/@global_avg).round rescue 0
|
||||
(1 / @global_avg).round rescue 0
|
||||
end
|
||||
|
||||
def apples
|
||||
|
|
@ -41,4 +40,4 @@ class AppleBar
|
|||
def with_restriction?
|
||||
FoodsoftConfig[:stop_ordering_under].present?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
class BankAccountConnector
|
||||
|
||||
class TextItem
|
||||
def initialize(text)
|
||||
@text = text
|
||||
|
|
@ -12,7 +11,6 @@ class BankAccountConnector
|
|||
def text
|
||||
@text
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class TextField
|
||||
|
|
@ -40,22 +38,17 @@ class BankAccountConnector
|
|||
end
|
||||
|
||||
class PasswordField < TextField
|
||||
|
||||
def type
|
||||
:password
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class HiddenField < TextField
|
||||
|
||||
def type
|
||||
:hidden
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
@@registered_classes = Set.new
|
||||
|
||||
def self.register(klass)
|
||||
|
|
@ -111,7 +104,7 @@ class BankAccountConnector
|
|||
nil
|
||||
end
|
||||
|
||||
def text_field(name, value=nil)
|
||||
def text_field(name, value = nil)
|
||||
@controls += [TextField.new(name, value, t(name))]
|
||||
end
|
||||
|
||||
|
|
@ -119,7 +112,7 @@ class BankAccountConnector
|
|||
@controls += [HiddenField.new(name, value, 'HIDDEN')]
|
||||
end
|
||||
|
||||
def password_field(name, value=nil)
|
||||
def password_field(name, value = nil)
|
||||
@controls += [PasswordField.new(name, value, t(name))]
|
||||
end
|
||||
|
||||
|
|
@ -139,7 +132,7 @@ class BankAccountConnector
|
|||
@bank_account.import_continuation_point = data
|
||||
end
|
||||
|
||||
def update_or_create_transaction(external_id, data={})
|
||||
def update_or_create_transaction(external_id, data = {})
|
||||
@bank_account.bank_transactions.where(external_id: external_id).first_or_create.update(data)
|
||||
@count += 1
|
||||
end
|
||||
|
|
@ -155,8 +148,9 @@ class BankAccountConnector
|
|||
def dump
|
||||
end
|
||||
|
||||
def t(key, args={})
|
||||
def t(key, args = {})
|
||||
return t(".fields.#{key}") unless key.is_a? String
|
||||
|
||||
I18n.t 'bank_account_connector' + key, args
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
class BankAccountConnectorExternal < BankAccountConnector
|
||||
|
||||
def load(data)
|
||||
@connector = create_connector
|
||||
@connector.load data
|
||||
|
|
@ -23,9 +22,9 @@ class BankAccountConnectorExternal < BankAccountConnector
|
|||
|
||||
def import(data)
|
||||
return false unless connector_login(data)
|
||||
|
||||
connector_import
|
||||
connector_logout
|
||||
true
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,14 +1,15 @@
|
|||
class BankAccountInformationImporter
|
||||
|
||||
def initialize(bank_account)
|
||||
@bank_account = bank_account
|
||||
end
|
||||
|
||||
def import!(content)
|
||||
return nil if content.empty?
|
||||
|
||||
data = JSON.parse content, symbolize_names: true
|
||||
|
||||
return 0 if data.empty?
|
||||
|
||||
booked = data.fetch(:transactions, {}).fetch(:booked, [])
|
||||
|
||||
ret = 0
|
||||
|
|
@ -18,17 +19,17 @@ class BankAccountInformationImporter
|
|||
entityAccount = amount < 0 ? t[:creditorAccount] : t[:debtorAccount]
|
||||
|
||||
@bank_account.bank_transactions.where(external_id: t[:transactionId]).first_or_create.update({
|
||||
date: t[:bookingDate],
|
||||
amount: amount,
|
||||
iban: entityAccount && entityAccount[:iban],
|
||||
reference: t[:remittanceInformationUnstructured],
|
||||
text: entityName,
|
||||
receipt: t[:additionalInformation],
|
||||
})
|
||||
date: t[:bookingDate],
|
||||
amount: amount,
|
||||
iban: entityAccount && entityAccount[:iban],
|
||||
reference: t[:remittanceInformationUnstructured],
|
||||
text: entityName,
|
||||
receipt: t[:additionalInformation],
|
||||
})
|
||||
ret += 1
|
||||
end
|
||||
|
||||
balances = Hash[ data[:balances] ? data[:balances].map { |b| [b[:balanceType], b[:balanceAmount]] } : [] ]
|
||||
balances = Hash[data[:balances] ? data[:balances].map { |b| [b[:balanceType], b[:balanceAmount]] } : []]
|
||||
balance = balances.values.first
|
||||
%w(closingBooked expected authorised openingBooked interimAvailable forwardAvailable nonInvoiced).each do |type|
|
||||
value = balances[type]
|
||||
|
|
@ -51,5 +52,4 @@ class BankAccountInformationImporter
|
|||
def parse_account_information_amount(value)
|
||||
value && value[:amount].to_f
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
class BankTransactionReference
|
||||
|
||||
# parses a string from a bank transaction field
|
||||
def self.parse(data)
|
||||
m = /(^|[^\w\.])FS(?<group>\d+)(\.(?<user>\d+))?(?<parts>([A-Za-z]+\d+(\.\d+)?)+)([^\w\.]|$)/.match(data)
|
||||
|
|
@ -30,5 +29,4 @@ class BankTransactionReference
|
|||
}
|
||||
}
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -6,12 +6,10 @@ module DateTimeAttributeValidate
|
|||
include DateTimeAttribute
|
||||
|
||||
module ClassMethods
|
||||
|
||||
def date_time_attribute(*attributes)
|
||||
super
|
||||
|
||||
attributes.each do |attribute|
|
||||
|
||||
validate -> { self.send("#{attribute}_datetime_value_valid") }
|
||||
|
||||
# allow resetting the field to nil
|
||||
|
|
@ -39,10 +37,10 @@ module DateTimeAttributeValidate
|
|||
|
||||
# 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')}
|
||||
self.instance_variable_get("@#{attribute}_date_value") || self.send("#{attribute}_date").try { |e| e.strftime('%Y-%m-%d') }
|
||||
end
|
||||
define_method("#{attribute}_time_value") do
|
||||
self.instance_variable_get("@#{attribute}_time_value") || self.send("#{attribute}_time").try {|e| e.strftime('%H:%M')}
|
||||
self.instance_variable_get("@#{attribute}_time_value") || self.send("#{attribute}_time").try { |e| e.strftime('%H:%M') }
|
||||
end
|
||||
|
||||
private
|
||||
|
|
@ -58,9 +56,7 @@ module DateTimeAttributeValidate
|
|||
errors.add(attribute, "is not a valid time") # @todo I18n
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -19,15 +19,15 @@ class FinancialTransactionsCsv < RenderCSV
|
|||
def data
|
||||
@object.includes(:user, :ordergroup, :financial_transaction_type).each do |t|
|
||||
yield [
|
||||
t.created_on,
|
||||
t.ordergroup_id,
|
||||
t.ordergroup_name,
|
||||
show_user(t.user),
|
||||
t.financial_transaction_type.financial_transaction_class.name,
|
||||
t.financial_transaction_type.name,
|
||||
t.note,
|
||||
number_to_currency(t.amount)
|
||||
]
|
||||
t.created_on,
|
||||
t.ordergroup_id,
|
||||
t.ordergroup_name,
|
||||
show_user(t.user),
|
||||
t.financial_transaction_type.financial_transaction_class.name,
|
||||
t.financial_transaction_type.name,
|
||||
t.note,
|
||||
number_to_currency(t.amount)
|
||||
]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ module Foodsoft
|
|||
# Please be thoughful when choosing names as to avoid collisions.
|
||||
# Do not put non-public info in variables.
|
||||
module ExpansionVariables
|
||||
|
||||
ACTIVE_MONTHS = 3
|
||||
|
||||
# @return [Hash] Variables and their values
|
||||
|
|
@ -16,31 +15,31 @@ module Foodsoft
|
|||
|
||||
# Hash of variables. Note that keys are Strings.
|
||||
@@variables = {
|
||||
'scope' => ->{ FoodsoftConfig.scope },
|
||||
'name' => ->{ FoodsoftConfig[:name] },
|
||||
'contact.street' => ->{ FoodsoftConfig[:contact][:street] },
|
||||
'contact.zip_code' => ->{ FoodsoftConfig[:contact][:zip_code] },
|
||||
'contact.city' => ->{ FoodsoftConfig[:contact][:city] },
|
||||
'contact.country' => ->{ FoodsoftConfig[:contact][:country] },
|
||||
'contact.email' => ->{ FoodsoftConfig[:contact][:email] },
|
||||
'contact.phone' => ->{ FoodsoftConfig[:contact][:phone] },
|
||||
'price_markup' => ->{ FoodsoftConfig[:price_markup] },
|
||||
'homepage' => ->{ FoodsoftConfig[:homepage] },
|
||||
'scope' => -> { FoodsoftConfig.scope },
|
||||
'name' => -> { FoodsoftConfig[:name] },
|
||||
'contact.street' => -> { FoodsoftConfig[:contact][:street] },
|
||||
'contact.zip_code' => -> { FoodsoftConfig[:contact][:zip_code] },
|
||||
'contact.city' => -> { FoodsoftConfig[:contact][:city] },
|
||||
'contact.country' => -> { FoodsoftConfig[:contact][:country] },
|
||||
'contact.email' => -> { FoodsoftConfig[:contact][:email] },
|
||||
'contact.phone' => -> { FoodsoftConfig[:contact][:phone] },
|
||||
'price_markup' => -> { FoodsoftConfig[:price_markup] },
|
||||
'homepage' => -> { FoodsoftConfig[:homepage] },
|
||||
|
||||
'help_url' => ->{ FoodsoftConfig[:help_url] },
|
||||
'applepear_url' => ->{ FoodsoftConfig[:applepear_url] },
|
||||
'help_url' => -> { FoodsoftConfig[:help_url] },
|
||||
'applepear_url' => -> { FoodsoftConfig[:applepear_url] },
|
||||
|
||||
'foodsoft.url' => ->{ FoodsoftConfig[:foodsoft_url] },
|
||||
'foodsoft.version' => Foodsoft::VERSION,
|
||||
'foodsoft.revision' => Foodsoft::REVISION,
|
||||
'foodsoft.url' => -> { FoodsoftConfig[:foodsoft_url] },
|
||||
'foodsoft.version' => Foodsoft::VERSION,
|
||||
'foodsoft.revision' => Foodsoft::REVISION,
|
||||
|
||||
'user_count' => ->{ User.undeleted.count },
|
||||
'ordergroup_count' => ->{ Ordergroup.undeleted.count },
|
||||
'active_ordergroup_count' => ->{ active_ordergroup_count },
|
||||
'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} }
|
||||
'user_count' => -> { User.undeleted.count },
|
||||
'ordergroup_count' => -> { Ordergroup.undeleted.count },
|
||||
'active_ordergroup_count' => -> { active_ordergroup_count },
|
||||
'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 } }
|
||||
}
|
||||
|
||||
# Return expanded variable
|
||||
|
|
@ -60,7 +59,6 @@ module Foodsoft
|
|||
end
|
||||
end
|
||||
|
||||
|
||||
# @return [Number] Number of ordergroups that have been active in the past 3 months
|
||||
def self.active_ordergroup_count
|
||||
GroupOrder
|
||||
|
|
@ -78,10 +76,9 @@ module Foodsoft
|
|||
# @return [String] Comma-separated list of suppliers that has been ordered from in the past 3 months
|
||||
def self.active_suppliers
|
||||
Supplier.joins(:orders)
|
||||
.where('orders.starts > ?', ACTIVE_MONTHS.months.ago)
|
||||
.order(:name).select(:name).distinct
|
||||
.map(&:name).join(', ')
|
||||
.where('orders.starts > ?', ACTIVE_MONTHS.months.ago)
|
||||
.order(:name).select(:name).distinct
|
||||
.map(&:name).join(', ')
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
# encoding: utf-8
|
||||
#
|
||||
# Foodcoop-specific configuration.
|
||||
#
|
||||
# This is loaded from +config/app_config.yml+, which contains a root
|
||||
|
|
@ -34,7 +32,6 @@
|
|||
# then you can whitelist specific attributes setting them to +false+.
|
||||
#
|
||||
class FoodsoftConfig
|
||||
|
||||
# @!attribute scope
|
||||
# Returns the current foodcoop scope for the multicoops feature, otherwise
|
||||
# the value of the foodcoop configuration key +default_scope+ is used.
|
||||
|
|
@ -61,7 +58,6 @@ class FoodsoftConfig
|
|||
end
|
||||
|
||||
class << self
|
||||
|
||||
# Load and initialize foodcoop configuration file.
|
||||
# @param filename [String] Override configuration file
|
||||
def init(filename = APP_CONFIG_FILE)
|
||||
|
|
@ -135,6 +131,7 @@ class FoodsoftConfig
|
|||
# @return [Boolean] Whether storing succeeded (fails when key is not allowed to be set in database).
|
||||
def []=(key, value)
|
||||
return false unless allowed_key?(key)
|
||||
|
||||
value = normalize_value value
|
||||
# then update database
|
||||
if config[key] == value || (config[key].nil? && value == false)
|
||||
|
|
@ -147,13 +144,13 @@ class FoodsoftConfig
|
|||
# or store
|
||||
RailsSettings::CachedSettings["foodcoop.#{self.scope}.#{key}"] = value
|
||||
end
|
||||
return true
|
||||
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.map! { |k| k.gsub(/^foodcoop\.#{self.scope}\./, '') }
|
||||
keys += config.keys
|
||||
keys.map(&:to_s).uniq
|
||||
end
|
||||
|
|
@ -183,22 +180,20 @@ class FoodsoftConfig
|
|||
def allowed_key?(key)
|
||||
# fast check for keys without nesting
|
||||
if self.config[:protected].include? key
|
||||
return !self.config[:protected][key]
|
||||
!self.config[:protected][key]
|
||||
else
|
||||
return !self.config[:protected][:all]
|
||||
!self.config[:protected][:all]
|
||||
end
|
||||
# @todo allow to check nested keys as well
|
||||
end
|
||||
|
||||
# @return [Hash] Full configuration.
|
||||
def to_hash
|
||||
Hash[keys.map {|k| [k, self[k]]} ]
|
||||
keys.map { |k| [k, self[k]] }.to_h
|
||||
end
|
||||
|
||||
# for using active_model_serializer in the api/v1/configs controller
|
||||
alias :read_attribute_for_serialization :[]
|
||||
|
||||
protected
|
||||
alias read_attribute_for_serialization []
|
||||
|
||||
# @!attribute default_config
|
||||
# Returns the program-default foodcoop configuration.
|
||||
|
|
@ -223,11 +218,11 @@ class FoodsoftConfig
|
|||
# @return [Hash] Default configuration values
|
||||
mattr_accessor :default_config
|
||||
|
||||
|
||||
private
|
||||
|
||||
def set_config(foodcoop)
|
||||
raise "No config for this environment (#{foodcoop}) available!" if APP_CONFIG[foodcoop].nil?
|
||||
|
||||
self.config = APP_CONFIG[foodcoop]
|
||||
self.scope = foodcoop
|
||||
set_missing
|
||||
|
|
@ -288,20 +283,18 @@ class FoodsoftConfig
|
|||
|
||||
# Normalize value recursively (which can be entered as strings, but we want to store it properly)
|
||||
def normalize_value(value)
|
||||
value = value.map{|v| normalize_value(v)} if value.is_a? Array
|
||||
value = value.map { |v| normalize_value(v) } if value.is_a? Array
|
||||
if value.is_a? Hash
|
||||
value = ActiveSupport::HashWithIndifferentAccess[ value.to_a.map{|a| [a[0], normalize_value(a[1])]} ]
|
||||
value = ActiveSupport::HashWithIndifferentAccess[value.to_a.map { |a| [a[0], normalize_value(a[1])] }]
|
||||
end
|
||||
case value
|
||||
when 'true' then true
|
||||
when 'false' then false
|
||||
when /^[-+0-9]+$/ then value.to_i
|
||||
when /^[-+0-9.]+([eE][-+0-9]+)?$/ then value.to_f
|
||||
when '' then nil
|
||||
else value
|
||||
when 'true' then true
|
||||
when 'false' then false
|
||||
when /^[-+0-9]+$/ then value.to_i
|
||||
when /^[-+0-9.]+([eE][-+0-9]+)?$/ then value.to_f
|
||||
when '' then nil
|
||||
else value
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
module FoodsoftDateUtil
|
||||
# find next occurence given a recurring ical string and time
|
||||
def self.next_occurrence(start=Time.now, from=start, options={})
|
||||
def self.next_occurrence(start = Time.now, from = start, options = {})
|
||||
occ = nil
|
||||
if options && options[:recurr]
|
||||
schedule = IceCube::Schedule.new(start)
|
||||
|
|
@ -25,5 +25,4 @@ module FoodsoftDateUtil
|
|||
p
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
# Foodsoft-file import
|
||||
class FoodsoftFile
|
||||
|
||||
# parses a string from a foodsoft-file
|
||||
# returns two arrays with articles and outlisted_articles
|
||||
# the parsed article is a simple hash
|
||||
|
|
@ -8,7 +7,7 @@ class FoodsoftFile
|
|||
SpreadsheetFile.parse file, options do |row, row_index|
|
||||
next if row[2].blank?
|
||||
|
||||
article = {:order_number => row[1],
|
||||
article = { :order_number => row[1],
|
||||
:name => row[2],
|
||||
:note => row[3],
|
||||
:manufacturer => row[4],
|
||||
|
|
@ -18,10 +17,9 @@ class FoodsoftFile
|
|||
:tax => row[8],
|
||||
:deposit => (row[9].nil? ? "0" : row[9]),
|
||||
:unit_quantity => row[10],
|
||||
:article_category => row[13]}
|
||||
:article_category => row[13] }
|
||||
status = row[0] && row[0].strip.downcase == 'x' ? :outlisted : nil
|
||||
yield status, article, row_index
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ require 'mail'
|
|||
require 'midi-smtp-server'
|
||||
|
||||
class FoodsoftMailReceiver < MidiSmtpServer::Smtpd
|
||||
|
||||
@@registered_classes = Set.new
|
||||
|
||||
def self.register(klass)
|
||||
|
|
@ -46,6 +45,7 @@ class FoodsoftMailReceiver < MidiSmtpServer::Smtpd
|
|||
m = /(?<foodcoop>[^@\.]+)\.(?<address>[^@]+)(@(?<hostname>[^@]+))?/.match recipient
|
||||
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]
|
||||
|
||||
@@registered_classes.each do |klass|
|
||||
|
|
@ -57,5 +57,4 @@ class FoodsoftMailReceiver < MidiSmtpServer::Smtpd
|
|||
|
||||
raise "invalid format for recipient"
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
require 'csv'
|
||||
|
||||
class OrderCsv < RenderCSV
|
||||
|
||||
def header
|
||||
[
|
||||
OrderArticle.human_attribute_name(:units_to_order),
|
||||
|
|
@ -17,15 +16,14 @@ class OrderCsv < RenderCSV
|
|||
def data
|
||||
@object.order_articles.ordered.includes([:article, :article_price]).all.map do |oa|
|
||||
yield [
|
||||
oa.units_to_order,
|
||||
oa.article.order_number,
|
||||
oa.article.name,
|
||||
oa.article.unit,
|
||||
oa.price.unit_quantity > 1 ? oa.price.unit_quantity : nil,
|
||||
number_to_currency(oa.price.price * oa.price.unit_quantity),
|
||||
number_to_currency(oa.total_price)
|
||||
]
|
||||
oa.units_to_order,
|
||||
oa.article.order_number,
|
||||
oa.article.name,
|
||||
oa.article.unit,
|
||||
oa.price.unit_quantity > 1 ? oa.price.unit_quantity : nil,
|
||||
number_to_currency(oa.price.price * oa.price.unit_quantity),
|
||||
number_to_currency(oa.total_price)
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
class OrderPdf < RenderPDF
|
||||
|
||||
attr_reader :order
|
||||
|
||||
def initialize(order, options = {})
|
||||
|
|
@ -9,9 +8,9 @@ class OrderPdf < RenderPDF
|
|||
end
|
||||
|
||||
def nice_table(name, data, dimrows = [])
|
||||
name_options = {size: 10, style: :bold}
|
||||
name_options = { size: 10, style: :bold }
|
||||
name_height = height_of name, name_options
|
||||
made_table = make_table data, width: bounds.width, cell_style: {size: 8, overflow: :shrink_to_fit} do |table|
|
||||
made_table = make_table data, width: bounds.width, cell_style: { size: 8, overflow: :shrink_to_fit } do |table|
|
||||
# borders
|
||||
table.cells.borders = [:bottom]
|
||||
table.cells.padding_top = 2
|
||||
|
|
@ -64,29 +63,29 @@ class OrderPdf < RenderPDF
|
|||
end
|
||||
|
||||
def group_order_articles(ordergroup)
|
||||
GroupOrderArticle.
|
||||
includes(:group_order).
|
||||
where(group_orders: {order_id: @orders, ordergroup_id: ordergroup})
|
||||
GroupOrderArticle
|
||||
.includes(:group_order)
|
||||
.where(group_orders: { order_id: @orders, ordergroup_id: ordergroup })
|
||||
end
|
||||
|
||||
def order_articles
|
||||
OrderArticle.
|
||||
ordered.
|
||||
includes(article: :supplier).
|
||||
includes(group_order_articles: {group_order: :ordergroup}).
|
||||
where(order: @orders).
|
||||
order('suppliers.name, articles.name, groups.name').
|
||||
preload(:article_price)
|
||||
OrderArticle
|
||||
.ordered
|
||||
.includes(article: :supplier)
|
||||
.includes(group_order_articles: { group_order: :ordergroup })
|
||||
.where(order: @orders)
|
||||
.order('suppliers.name, articles.name, groups.name')
|
||||
.preload(:article_price)
|
||||
end
|
||||
|
||||
def ordergroups(offset = nil, limit = nil)
|
||||
result = GroupOrder.
|
||||
ordered.
|
||||
where(order: @orders).
|
||||
group('groups.id').
|
||||
offset(offset).
|
||||
limit(limit).
|
||||
pluck('groups.name', 'SUM(group_orders.price)', 'ordergroup_id', 'SUM(group_orders.transport)')
|
||||
result = GroupOrder
|
||||
.ordered
|
||||
.where(order: @orders)
|
||||
.group('groups.id')
|
||||
.offset(offset)
|
||||
.limit(limit)
|
||||
.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]
|
||||
|
|
@ -113,8 +112,8 @@ class OrderPdf < RenderPDF
|
|||
|
||||
# get quantity for each article and ordergroup
|
||||
goa_records = group_order_articles(group_ids)
|
||||
.group('group_order_articles.order_article_id, group_orders.ordergroup_id')
|
||||
.pluck('group_order_articles.order_article_id', 'group_orders.ordergroup_id', 'SUM(COALESCE(group_order_articles.result, group_order_articles.quantity))')
|
||||
.group('group_order_articles.order_article_id, group_orders.ordergroup_id')
|
||||
.pluck('group_order_articles.order_article_id', 'group_orders.ordergroup_id', 'SUM(COALESCE(group_order_articles.result, group_order_articles.quantity))')
|
||||
|
||||
# transform the flat list of results in a hash (with the article as key), which contains an array for all ordergroups
|
||||
results = goa_records.group_by(&:first).transform_values do |value|
|
||||
|
|
@ -135,20 +134,19 @@ class OrderPdf < RenderPDF
|
|||
|
||||
def each_group_order_article_for_ordergroup(ordergroup, &block)
|
||||
group_order_articles(ordergroup)
|
||||
.includes(order_article: {article: [:supplier]})
|
||||
.includes(order_article: { article: [:supplier] })
|
||||
.order('suppliers.name, articles.name')
|
||||
.preload(order_article: [:article_price, :order])
|
||||
.each(&block)
|
||||
end
|
||||
|
||||
def stock_ordergroup_name
|
||||
users = GroupOrder.stock.
|
||||
eager_load(:updated_by).
|
||||
where(order: @orders).
|
||||
map(&:updated_by).
|
||||
map{ |u| u.try(&:name) || '?' }
|
||||
users = GroupOrder.stock
|
||||
.eager_load(:updated_by)
|
||||
.where(order: @orders)
|
||||
.map(&:updated_by)
|
||||
.map { |u| u.try(&:name) || '?' }
|
||||
|
||||
I18n.t('model.group_order.stock_ordergroup_name', user: users.uniq.sort.join(', '))
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
|
||||
class OrderTxt
|
||||
def initialize(order, options={})
|
||||
def initialize(order, options = {})
|
||||
@order = order
|
||||
end
|
||||
|
||||
|
|
@ -16,16 +15,16 @@ class OrderTxt
|
|||
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 += "%8s %8s %s\n"%[I18n.t('orders.fax.number'), I18n.t('orders.fax.amount'), I18n.t('orders.fax.name')]
|
||||
text += "%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|
|
||||
text += "%8s %8d %s\n"%[oa.article.order_number, oa.units_to_order.to_i, oa.article.name]
|
||||
text += "%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.open("#{Rails.root}/tmp/#{self.class.to_s.underscore}.txt", 'w') {|f| f.write(to_csv.force_encoding("UTF-8")) }
|
||||
File.open("#{Rails.root}/tmp/#{self.class.to_s.underscore}.txt", 'w') { |f| f.write(to_csv.force_encoding("UTF-8")) }
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ require 'csv'
|
|||
class RenderCSV
|
||||
include ActionView::Helpers::NumberHelper
|
||||
|
||||
def initialize(object, options={})
|
||||
def initialize(object, options = {})
|
||||
@object = object
|
||||
@options = options
|
||||
# defaults to please Microsoft Excel ...
|
||||
|
|
@ -13,12 +13,12 @@ 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
|
||||
end
|
||||
data {|d| csv << d}
|
||||
data { |d| csv << d }
|
||||
end
|
||||
ret.encode(@options[:encoding], invalid: :replace, undef: :replace)
|
||||
end
|
||||
|
|
@ -34,11 +34,11 @@ class RenderCSV
|
|||
# Helper method to test pdf via rails console: OrderCsv.new(order).save_tmp
|
||||
def save_tmp
|
||||
encoding = @options[:encoding] || 'UTF-8'
|
||||
File.open("#{Rails.root}/tmp/#{self.class.to_s.underscore}.csv", 'w') {|f| f.write(to_csv.force_encoding(encoding)) }
|
||||
File.open("#{Rails.root}/tmp/#{self.class.to_s.underscore}.csv", 'w') { |f| f.write(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: ''}))
|
||||
def number_to_currency(number, options = {})
|
||||
super(number, options.merge({ unit: '' }))
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
require 'prawn/measurement_extensions'
|
||||
|
||||
class RotatedCell < Prawn::Table::Cell::Text
|
||||
|
||||
def initialize(pdf, text, options={})
|
||||
def initialize(pdf, text, options = {})
|
||||
options[:content] = text
|
||||
options[:valign] = :center
|
||||
options[:align] = :center
|
||||
|
|
@ -32,8 +31,8 @@ class RotatedCell < Prawn::Table::Cell::Text
|
|||
def draw_borders(pt)
|
||||
@pdf.mask(:line_width, :stroke_color) do
|
||||
x, y = pt
|
||||
from = [[x - skew , y + (border_top_width / 2.0)],
|
||||
to = [x, y - height - (border_bottom_width / 2.0)]]
|
||||
from = [[x - skew, y + (border_top_width / 2.0)],
|
||||
to = [x, y - height - (border_bottom_width / 2.0)]]
|
||||
|
||||
@pdf.line_width = @border_widths[3]
|
||||
@pdf.stroke_color = @border_colors[3]
|
||||
|
|
@ -47,11 +46,10 @@ class RotatedCell < Prawn::Table::Cell::Text
|
|||
with_text_color do
|
||||
text_box(width: spanned_content_width + FPTolerance + skew,
|
||||
height: spanned_content_height + FPTolerance,
|
||||
at: [1-skew, @pdf.cursor]).render
|
||||
at: [1 - skew, @pdf.cursor]).render
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class RenderPDF < Prawn::Document
|
||||
|
|
@ -116,17 +114,17 @@ class RenderPDF < Prawn::Document
|
|||
end
|
||||
|
||||
def to_pdf
|
||||
body # Add content, which is defined in subclasses
|
||||
render # Render pdf
|
||||
body # Add content, which is defined in subclasses
|
||||
render # Render pdf
|
||||
end
|
||||
|
||||
# Helper method to test pdf via rails console: OrderByGroups.new(order).save_tmp
|
||||
def save_tmp
|
||||
File.open("#{Rails.root}/tmp/#{self.class.to_s.underscore}.pdf", 'w') {|f| f.write(to_pdf.force_encoding("UTF-8")) }
|
||||
File.open("#{Rails.root}/tmp/#{self.class.to_s.underscore}.pdf", 'w') { |f| f.write(to_pdf.force_encoding("UTF-8")) }
|
||||
end
|
||||
|
||||
# @todo avoid underscore instead of unicode whitespace in pdf :/
|
||||
def number_to_currency(number, options={})
|
||||
def number_to_currency(number, options = {})
|
||||
super(number, options).gsub("\u202f", ' ') if number
|
||||
end
|
||||
|
||||
|
|
@ -136,7 +134,7 @@ class RenderPDF < Prawn::Document
|
|||
end
|
||||
|
||||
# add pagebreak or vertical whitespace, depending on configuration
|
||||
def down_or_page(space=10)
|
||||
def down_or_page(space = 10)
|
||||
if @first_page
|
||||
@first_page = false
|
||||
return
|
||||
|
|
@ -155,7 +153,7 @@ class RenderPDF < Prawn::Document
|
|||
end
|
||||
|
||||
# return whether pagebreak or vertical whitespace is used for breaks
|
||||
def pdf_add_page_breaks?(docid=nil)
|
||||
def pdf_add_page_breaks?(docid = nil)
|
||||
docid ||= self.class.name.underscore
|
||||
cfg = FoodsoftConfig[:pdf_add_page_breaks]
|
||||
if cfg.is_a? Array
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
require 'roo'
|
||||
|
||||
class SpreadsheetFile
|
||||
|
||||
def self.parse(file, options = {})
|
||||
filepath = file.is_a?(String) ? file : file.to_path
|
||||
filename = options.delete(:filename) || filepath
|
||||
fileext = File.extname(filename)
|
||||
options[:csv_options] = {col_sep: ';', encoding: 'utf-8'}.merge(options[:csv_options]||{})
|
||||
s = Roo::Spreadsheet.open(filepath, options.merge({extension: fileext}))
|
||||
options[:csv_options] = { col_sep: ';', encoding: 'utf-8' }.merge(options[:csv_options] || {})
|
||||
s = Roo::Spreadsheet.open(filepath, options.merge({ extension: fileext }))
|
||||
|
||||
row_index = 1
|
||||
s.each do |row|
|
||||
|
|
@ -20,5 +19,4 @@ class SpreadsheetFile
|
|||
end
|
||||
row_index
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -69,9 +69,11 @@ namespace :foodsoft do
|
|||
BankAccount.find_each do |ba|
|
||||
importer = ba.find_connector
|
||||
next unless importer
|
||||
|
||||
importer.load nil
|
||||
ok = importer.import nil
|
||||
next unless ok
|
||||
|
||||
importer.finish
|
||||
assign_count = ba.assign_unlinked_transactions
|
||||
rake_say "#{ba.name}: imported #{importer.count}, assigned #{assign_count}"
|
||||
|
|
|
|||
|
|
@ -7,16 +7,16 @@ module Colors
|
|||
def colorize(text, color_code)
|
||||
"\033[#{color_code}m#{text}\033[0m"
|
||||
end
|
||||
|
||||
|
||||
{
|
||||
:black => 30,
|
||||
:red => 31,
|
||||
:green => 32,
|
||||
:yellow => 33,
|
||||
:blue => 34,
|
||||
:magenta => 35,
|
||||
:cyan => 36,
|
||||
:white => 37
|
||||
:black => 30,
|
||||
:red => 31,
|
||||
:green => 32,
|
||||
:yellow => 33,
|
||||
:blue => 34,
|
||||
:magenta => 35,
|
||||
:cyan => 36,
|
||||
:white => 37
|
||||
}.each do |key, color_code|
|
||||
define_method key do |text|
|
||||
colorize(text, color_code)
|
||||
|
|
@ -49,9 +49,9 @@ end
|
|||
|
||||
def setup_bundler
|
||||
puts yellow "Installing bundler if not installed..."
|
||||
%x( if [ -z `which bundle` ]; then gem install bundler --no-rdoc --no-ri; fi )
|
||||
%x(if [ -z `which bundle` ]; then gem install bundler --no-rdoc --no-ri; fi)
|
||||
puts yellow "Executing bundle install..."
|
||||
%x( bundle install )
|
||||
%x(bundle install)
|
||||
end
|
||||
|
||||
def setup_database
|
||||
|
|
@ -61,18 +61,18 @@ def setup_database
|
|||
return nil
|
||||
end
|
||||
return nil if skip?(file)
|
||||
|
||||
database = ask("What kind of database do you use?\nOptions:\n(1) MySQL\n(2) SQLite", ["1","2"])
|
||||
|
||||
database = ask("What kind of database do you use?\nOptions:\n(1) MySQL\n(2) SQLite", ["1", "2"])
|
||||
if database == "1"
|
||||
puts yellow "Using MySQL..."
|
||||
%x( cp #{Rails.root.join("#{file}.MySQL_SAMPLE")} #{Rails.root.join(file)} )
|
||||
%x(cp #{Rails.root.join("#{file}.MySQL_SAMPLE")} #{Rails.root.join(file)})
|
||||
elsif database == "2"
|
||||
puts yellow "Using SQLite..."
|
||||
%x( cp #{Rails.root.join("#{file}.SQLite_SAMPLE")} #{Rails.root.join(file)} )
|
||||
%x(cp #{Rails.root.join("#{file}.SQLite_SAMPLE")} #{Rails.root.join(file)})
|
||||
end
|
||||
|
||||
|
||||
reminder(file)
|
||||
|
||||
|
||||
puts blue "IMPORTANT: Edit (rake-generated) config/database.yml with valid username and password for EACH env before continuing!"
|
||||
finished = ask("Finished?\nOptions:\n(y) Yes", ["y"])
|
||||
if finished
|
||||
|
|
@ -86,27 +86,28 @@ def setup_app_config
|
|||
file = 'config/app_config.yml'
|
||||
sample = Rails.root.join("#{file}.SAMPLE")
|
||||
return nil if skip?(file)
|
||||
|
||||
|
||||
puts yellow "Copying #{file}..."
|
||||
%x( cp #{sample} #{Rails.root.join(file)} )
|
||||
%x(cp #{sample} #{Rails.root.join(file)})
|
||||
reminder(file)
|
||||
end
|
||||
|
||||
def setup_development
|
||||
file = 'config/environments/development.rb'
|
||||
return nil if skip?(file)
|
||||
|
||||
|
||||
puts yellow "Copying #{file}..."
|
||||
%x( cp #{Rails.root.join("#{file}.SAMPLE")} #{Rails.root.join(file)} )
|
||||
%x(cp #{Rails.root.join("#{file}.SAMPLE")} #{Rails.root.join(file)})
|
||||
reminder(file)
|
||||
end
|
||||
|
||||
def start_mailcatcher
|
||||
return nil if ENV['MAILCATCHER_PORT'] # skip when it has an existing Docker container
|
||||
mailcatcher = ask("Do you want to start mailcatcher?\nOptions:\n(y) Yes\n(n) No", ["y","n"])
|
||||
|
||||
mailcatcher = ask("Do you want to start mailcatcher?\nOptions:\n(y) Yes\n(n) No", ["y", "n"])
|
||||
if mailcatcher === "y"
|
||||
puts yellow "Starting mailcatcher at http://localhost:1080..."
|
||||
%x( mailcatcher )
|
||||
%x(mailcatcher)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -128,7 +129,7 @@ end
|
|||
|
||||
def skip?(file)
|
||||
output = false
|
||||
skip = ask(cyan("We found #{file}!\nOptions:\n(1) Skip step\n(2) Force rewrite"), ["1","2"]) if File.exists?(Rails.root.join(file))
|
||||
skip = ask(cyan("We found #{file}!\nOptions:\n(1) Skip step\n(2) Force rewrite"), ["1", "2"]) if File.exists?(Rails.root.join(file))
|
||||
output = true if skip == "1"
|
||||
output
|
||||
end
|
||||
|
|
@ -145,4 +146,3 @@ def capture_stdout
|
|||
ensure
|
||||
$stdout = STDOUT
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
# for each foodcoop is used.
|
||||
|
||||
namespace :multicoops do
|
||||
|
||||
desc 'Runs a specific rake task for each registered foodcoop, use rake multicoops:run TASK=db:migrate'
|
||||
task :run => :environment do
|
||||
task_to_run = ENV['TASK']
|
||||
|
|
@ -14,7 +13,7 @@ namespace :multicoops do
|
|||
Rake::Task[task_to_run].execute
|
||||
rescue => error
|
||||
last_error = error
|
||||
ExceptionNotifier.notify_exception(error, data: {foodcoop: coop})
|
||||
ExceptionNotifier.notify_exception(error, data: { foodcoop: coop })
|
||||
end
|
||||
end
|
||||
raise last_error if last_error
|
||||
|
|
@ -27,11 +26,9 @@ namespace :multicoops do
|
|||
rake_say "Run '#{task_to_run}' for #{ENV['FOODCOOP']}"
|
||||
Rake::Task[task_to_run].execute
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
# Helper
|
||||
def rake_say(message)
|
||||
puts message unless Rake.application.options.silent
|
||||
puts message unless Rake.application.options.silent
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@ require "resque/tasks"
|
|||
|
||||
def run_worker(queue, count = 1)
|
||||
puts "Starting #{count} worker(s) with QUEUE: #{queue}"
|
||||
ops = {:pgroup => true, :err => ["log/resque_worker_foodsoft_notifier.log", "a"],
|
||||
:out => ["log/resque_worker_foodsoft_notifier.log", "a"]}
|
||||
env_vars = {"QUEUE" => queue.to_s, "PIDFILE" => "tmp/pids/resque_worker_foodsoft_notifier.pid"}
|
||||
ops = { :pgroup => true, :err => ["log/resque_worker_foodsoft_notifier.log", "a"],
|
||||
:out => ["log/resque_worker_foodsoft_notifier.log", "a"] }
|
||||
env_vars = { "QUEUE" => queue.to_s, "PIDFILE" => "tmp/pids/resque_worker_foodsoft_notifier.pid" }
|
||||
count.times {
|
||||
## Using Kernel.spawn and Process.detach because regular system() call would
|
||||
## cause the processes to quit when capistrano finishes
|
||||
|
|
@ -21,7 +21,7 @@ namespace :resque do
|
|||
Rake::Task['resque:stop_workers'].invoke
|
||||
Rake::Task['resque:start_workers'].invoke
|
||||
end
|
||||
|
||||
|
||||
desc "Quit running workers"
|
||||
task :stop_workers do
|
||||
pids = File.read('tmp/pids/resque_worker_foodsoft_notifier.pid').split("\n")
|
||||
|
|
@ -33,9 +33,9 @@ namespace :resque do
|
|||
system(syscmd)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
desc "Start workers"
|
||||
task :start_workers do
|
||||
run_worker("foodsoft_notifier")
|
||||
run_worker("foodsoft_notifier")
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ begin
|
|||
|
||||
# Use `rspec` to run a single test. When a test fails in rake but not
|
||||
# with rspec, you can use the following to run a single test using rake:
|
||||
#RSpec::Core::RakeTask.new('spec:foo') do |t|
|
||||
# t.pattern = "spec/integration/foo_spec.rb"
|
||||
#end
|
||||
# RSpec::Core::RakeTask.new('spec:foo') do |t|
|
||||
# t.pattern = "spec/integration/foo_spec.rb"
|
||||
# end
|
||||
rescue LoadError
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
# Generic token verifier with foodcoop scope
|
||||
# @todo use +Rails.application.message_verifier+ when possible
|
||||
class TokenVerifier < ActiveSupport::MessageVerifier
|
||||
|
||||
def initialize(prefix)
|
||||
super(self.class.secret)
|
||||
@_prefix = prefix.is_a?(Array) ? prefix.join(':') : prefix.to_s
|
||||
end
|
||||
|
||||
def generate(message=nil)
|
||||
def generate(message = nil)
|
||||
fullmessage = [FoodsoftConfig.scope, @_prefix]
|
||||
fullmessage.append(message) unless message.nil?
|
||||
super(fullmessage)
|
||||
|
|
@ -18,6 +17,7 @@ class TokenVerifier < ActiveSupport::MessageVerifier
|
|||
raise InvalidMessage unless r.is_a?(Array) && r.length >= 2 && r.length <= 3
|
||||
raise InvalidScope unless r[0] == FoodsoftConfig.scope
|
||||
raise InvalidPrefix unless r[1] == @_prefix
|
||||
|
||||
# return original message
|
||||
if r.length > 2
|
||||
r[2]
|
||||
|
|
@ -27,7 +27,9 @@ class TokenVerifier < ActiveSupport::MessageVerifier
|
|||
end
|
||||
|
||||
class InvalidMessage < ActiveSupport::MessageVerifier::InvalidSignature; end
|
||||
|
||||
class InvalidScope < ActiveSupport::MessageVerifier::InvalidSignature; end
|
||||
|
||||
class InvalidPrefix < ActiveSupport::MessageVerifier::InvalidSignature; end
|
||||
|
||||
protected
|
||||
|
|
@ -36,5 +38,4 @@ class TokenVerifier < ActiveSupport::MessageVerifier
|
|||
# secret_key_base for Rails 4, but Rails 3 initializer may still be used
|
||||
Foodsoft::Application.config.secret_key_base || Foodsoft::Application.config.secret_token
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue