167 lines
4.8 KiB
Ruby
167 lines
4.8 KiB
Ruby
class SupplierEmployeesSettings
|
|
attr_reader :dictionary, :employee_ids, :supplier
|
|
def initialize(supplier)
|
|
@supplier = supplier
|
|
@dictionary = (supplier.employee_settings_storage || {}).to_h
|
|
@employee_ids = supplier.employee_ids || []
|
|
end
|
|
|
|
def for_employee(employee)
|
|
return SupplierEmployeeSettings::NullObject.new unless employee.present?
|
|
if employee_ids.include? employee.id
|
|
settings = SupplierEmployeeSettings.new(self, employee, dictionary[employee.id])
|
|
else
|
|
settings = SupplierEmployeeSettings::NullObject.new
|
|
end
|
|
employee.settings = settings
|
|
end
|
|
|
|
def [](val)
|
|
val = val.to_s
|
|
if dictionary[val].is_a? SettingsPersistor
|
|
dictionary[val]
|
|
else
|
|
dictionary[val] = SettingsPersistor.new(self, dictionary[val])
|
|
end
|
|
end
|
|
|
|
def to_store!
|
|
supplier.employee_settings_storage = dictionary
|
|
end
|
|
|
|
def method_missing(m, *args)
|
|
dictionary.send(m, *args)
|
|
end
|
|
|
|
class SettingsPersistor < Hash
|
|
attr_reader :all_employees_settings
|
|
def initialize(all_employees_settings, options = {})
|
|
@all_employees_settings = all_employees_settings
|
|
self.replace options if options.is_a? Hash
|
|
end
|
|
|
|
alias_method :orig_setter, :[]=
|
|
def []=(*args)
|
|
orig_setter(*args)
|
|
all_employees_settings.to_store!
|
|
end
|
|
end
|
|
|
|
class SupplierEmployeeSettings
|
|
delegate :as_json, :to_json, to: :settings
|
|
attr_reader :employee, :settings, :all_employees_settings
|
|
class NullObject < ::NullObject
|
|
::Employee::DEFAULT_SETTINGS.each do |attribute, value|
|
|
if value == true or value == false
|
|
define_method("#{attribute}?"){ value }
|
|
end
|
|
define_method(attribute){ value }
|
|
end
|
|
def public_send(m, *args)
|
|
if ::Employee::DEFAULT_SETTINGS.has_key?(m.to_s)
|
|
::Employee::DEFAULT_SETTINGS[m.to_s]
|
|
else
|
|
nil # this time we will raise on further invocation, since then there is something wrong
|
|
end
|
|
end
|
|
|
|
def as_json
|
|
{}
|
|
end
|
|
end
|
|
|
|
def initialize(all_employees_settings, employee, settings = {})
|
|
@all_employees_settings = all_employees_settings
|
|
@employee = employee
|
|
@settings = Employee.default_settings.merge(settings || {})
|
|
end
|
|
|
|
def [](val)
|
|
settings[val.to_s]
|
|
end
|
|
|
|
def set(attribute, value, persist: false)
|
|
settings[attribute] = value
|
|
all_employees_settings[employee.id][attribute] = value
|
|
persist! if persist
|
|
self
|
|
end
|
|
|
|
def []=(attribute, value)
|
|
set attribute, value
|
|
end
|
|
|
|
def set!(attribute, value)
|
|
set attribute, value, persist: true
|
|
end
|
|
|
|
def update(params)
|
|
Employee::DEFAULT_SETTINGS.keys.each do |attribute|
|
|
if params.has_key?(attribute)
|
|
new_value = params.delete(attribute)
|
|
set attribute, new_value
|
|
end
|
|
end
|
|
params
|
|
end
|
|
|
|
def update!(params)
|
|
update params
|
|
persist!
|
|
params
|
|
end
|
|
|
|
def persist!
|
|
all_employees_settings.supplier.employee_settings_storage_will_change!
|
|
all_employees_settings.supplier.save
|
|
end
|
|
|
|
def supplier
|
|
all_employees_settings.supplier
|
|
end
|
|
|
|
# Parse a method name to its underlying operations
|
|
# settings.is_manager?
|
|
# is a getter for the attribute manager
|
|
# settings.is_manager!
|
|
# is a boolean setter to true for the attribute manager and persists the inderlying model
|
|
# without exclamation mark it is the same, but without persisting the model.
|
|
# settings.is_not_manager!
|
|
# is a boolean setter to false for the attribute manger.
|
|
# settings.manager
|
|
# is a normal accessor for the attribute manager
|
|
def parse_method_for_boolean_operation(method)
|
|
method = method.to_s
|
|
persist = false
|
|
attribute = method
|
|
set_value = nil
|
|
if method.end_with? '!'
|
|
persist = true
|
|
set_value = true
|
|
attribute.chop!
|
|
end
|
|
if method.end_with? '?'
|
|
# Always a getter, so no set_value
|
|
attribute.chop!
|
|
#attribute = attribute.from(7) if attribute.start_with? 'is_not'
|
|
attribute = attribute.from(3) if attribute.start_with? 'is_'
|
|
elsif method.start_with? 'is_not_'
|
|
set_value = false
|
|
attribute = attribute.from 7
|
|
elsif method.start_with? 'is_'
|
|
set_value = true
|
|
attribute = attribute.from 3
|
|
end
|
|
raise "Settings do not support attribute '#{attribute}'" unless Employee.default_settings.has_key?(attribute) # Do not return a nonexistent attribute
|
|
[attribute, set_value, persist]
|
|
end
|
|
|
|
def method_missing(m, *args)
|
|
attribute, set_value, persist = parse_method_for_boolean_operation(m)
|
|
return unless attribute # method cannot be used in the settings
|
|
return settings[attribute] if set_value.nil? # Getter operation, setting nil is not supported
|
|
set attribute, set_value, persist: persist
|
|
end
|
|
end
|
|
end
|