194 lines
6.6 KiB
Ruby
194 lines
6.6 KiB
Ruby
class Checkin::Updater
|
|
attr_reader :current_user, :checkin, :permitted_params
|
|
|
|
def initialize(current_user, params)
|
|
@current_user = current_user
|
|
id = params.require(:id)
|
|
@checkin = Checkin.find(id)
|
|
@permitted_params =
|
|
params
|
|
.require(:checkin)
|
|
.permit(
|
|
:note, :postal_code, :weather_id, :promotion_skipped_at,
|
|
tag_ids: [],
|
|
food_ids: [],
|
|
conditions_attributes: [:id, :value, :condition_id, :color_id, :position, :_destroy],
|
|
symptoms_attributes: [:id, :value, :symptom_id, :color_id, :position, :_destroy],
|
|
treatments_attributes: [:id, :value, :treatment_id, :is_taken, :color_id, :position, :_destroy]
|
|
)
|
|
.tap do |p|
|
|
set_most_recent_doses(p[:treatments_attributes])
|
|
update_trackables_positions(p)
|
|
p[:tag_ids] = [] if p[:tag_ids].nil?
|
|
p[:food_ids] = [] if p[:food_ids].nil?
|
|
end
|
|
end
|
|
|
|
def update!
|
|
checkin.update!(permitted_params.except(:postal_code))
|
|
|
|
if checkin.date.today?
|
|
save_most_recent_doses
|
|
save_most_recent_trackables_positions
|
|
end
|
|
update_trackable_usages
|
|
|
|
position = Position.find_or_create_by(postal_code: permitted_params[:postal_code])
|
|
|
|
if position.persisted?
|
|
checkin.position_id = position.id
|
|
checkin.save!
|
|
end
|
|
|
|
checkin
|
|
end
|
|
|
|
private
|
|
|
|
def update_trackables_positions(params)
|
|
%w[Condition Symptom Treatment].each do |trackable_class_name|
|
|
update_trackables_positions_on_destroy(trackable_class_name, params)
|
|
set_added_trackables_positions(trackable_class_name, params)
|
|
end
|
|
end
|
|
|
|
def update_trackables_positions_on_destroy(trackable_class_name, params)
|
|
trackables_attrs = trackables_attrs(trackable_class_name, params)
|
|
removed_trackables = removed_trackables_attrs(trackables_attrs)
|
|
removed_trackables.each do |removed_trackable|
|
|
trackables_attrs.each do |trackable|
|
|
next if trackable[:position].blank? ||
|
|
removed_trackable[:position].blank? ||
|
|
trackable[:position] <= removed_trackable[:position]
|
|
|
|
trackable[:position] -= 1
|
|
end
|
|
end
|
|
end
|
|
|
|
def set_added_trackables_positions(trackable_class_name, params)
|
|
trackables_attrs = trackables_attrs(trackable_class_name, params)
|
|
trackable_max = trackables_attrs.reject { |t| t[:position].blank? }.max_by { |t| t[:position] }
|
|
max_position = trackable_max.present? ? trackable_max[:position] : 0
|
|
added_trackables = added_trackables_attrs(trackables_attrs)
|
|
added_trackables.each do |added_trackable|
|
|
if added_trackable[:position].blank?
|
|
max_position += 1
|
|
added_trackable[:position] = max_position
|
|
end
|
|
end
|
|
end
|
|
|
|
def save_most_recent_trackables_positions
|
|
%w[condition symptom treatment].each do |trackable_type|
|
|
trackable_class = trackable_type.capitalize.constantize
|
|
trackables_attributes = permitted_params["#{trackable_type.pluralize}_attributes".to_sym]
|
|
next if trackables_attributes.blank?
|
|
trackables_attributes.each do |trackable_attrs|
|
|
trackable = trackable_class.find(trackable_attrs["#{trackable_type}_id".to_sym])
|
|
current_user.profile.set_most_recent_trackable_position(
|
|
trackable, trackable_attrs[:position]
|
|
)
|
|
end
|
|
end
|
|
end
|
|
|
|
def set_most_recent_doses(treatments_attrs)
|
|
return if treatments_attrs.blank?
|
|
|
|
added_trackables_attrs(treatments_attrs).each do |t|
|
|
t[:value] = current_user.profile.most_recent_dose_for(t[:treatment_id])
|
|
end
|
|
end
|
|
|
|
def save_most_recent_doses
|
|
treatments_attributes = permitted_params[:treatments_attributes]
|
|
return if treatments_attributes.blank?
|
|
treatments_with_doses = treatments_attributes.reject { |t| (t[:value].blank? || t[:is_taken].eql?("false")) }
|
|
return if treatments_with_doses.empty?
|
|
treatments_with_doses.each do |t|
|
|
current_user.profile.set_most_recent_dose(
|
|
t[:treatment_id], t[:value]
|
|
)
|
|
end
|
|
current_user.profile.save!
|
|
end
|
|
|
|
def update_trackable_usages
|
|
%w[Condition Symptom Treatment].each do |trackable_class_name|
|
|
update_removed_trackables_usages(trackable_class_name)
|
|
update_added_trackables_usages(trackable_class_name)
|
|
end
|
|
|
|
%w[Tag Food].each do |health_class_name|
|
|
update_health_factors_trackable_usages(health_class_name)
|
|
end
|
|
end
|
|
|
|
# For trackables that have been removed from checkin, look for TrackableUsage records
|
|
# for the current user. When a record exists with count 1 it's destroyed,
|
|
# else count is decremented
|
|
def update_removed_trackables_usages(trackable_class_name)
|
|
removed_trackables = removed_trackables_attrs(
|
|
trackables_attrs(trackable_class_name, permitted_params)
|
|
)
|
|
trackable_class = trackable_class_name.constantize
|
|
trackable_id_key = "#{trackable_class_name.downcase}_id".to_sym
|
|
removed_trackables.each do |t|
|
|
trackable_usage = TrackableUsage.find_by(
|
|
user: current_user,
|
|
trackable: trackable_class.find(t[trackable_id_key])
|
|
)
|
|
|
|
next if trackable_usage.blank?
|
|
|
|
if trackable_usage.count.eql?(1)
|
|
trackable_usage.destroy
|
|
else
|
|
trackable_usage.decrement! :count
|
|
end
|
|
end
|
|
end
|
|
|
|
def removed_trackables_attrs(trackables_attrs)
|
|
trackables_attrs.select { |attrs| attrs[:_destroy].eql?("1") }
|
|
end
|
|
|
|
def trackables_attrs(trackable_class_name, params)
|
|
attrs_key = "#{trackable_class_name.downcase.pluralize}_attributes".to_sym
|
|
trackables_attrs = params[attrs_key]
|
|
|
|
return [] if trackables_attrs.blank?
|
|
|
|
trackables_attrs
|
|
end
|
|
|
|
# For trackables that have been added to checkin, look for TrackableUsage records
|
|
# for the current user. When a record exists its count is incremented,
|
|
# else a new record is created
|
|
def update_added_trackables_usages(trackable_class_name)
|
|
added_trackables = added_trackables_attrs(
|
|
trackables_attrs(trackable_class_name, permitted_params)
|
|
)
|
|
trackable_class = trackable_class_name.constantize
|
|
trackable_id_key = "#{trackable_class_name.downcase}_id".to_sym
|
|
added_trackables.each do |t|
|
|
trackable = trackable_class.find(t[trackable_id_key])
|
|
TrackableUsage.create_or_update_by(user: current_user, trackable: trackable)
|
|
end
|
|
end
|
|
|
|
def added_trackables_attrs(trackables_attrs)
|
|
trackables_attrs.select { |attrs| attrs[:id].blank? }
|
|
end
|
|
|
|
def update_health_factors_trackable_usages(trackable_class_name)
|
|
trackable_class = trackable_class_name.constantize
|
|
trackable_key = "#{trackable_class_name.downcase}_ids"
|
|
|
|
trackable_class.where(id: permitted_params[trackable_key]).each do |health_factor|
|
|
TrackableUsage.create_or_update_by(user: current_user, trackable: health_factor)
|
|
end
|
|
end
|
|
end
|