Skip to content

Instantly share code, notes, and snippets.

@ricsdeol
Last active November 10, 2020 21:05
Show Gist options
  • Save ricsdeol/b325bfc2e1d01591a7c383a71f97e654 to your computer and use it in GitHub Desktop.
Save ricsdeol/b325bfc2e1d01591a7c383a71f97e654 to your computer and use it in GitHub Desktop.
Goals Ucase Exemple
require 'pp'
require 'bundler/inline'
gemfile do
source 'https://rubygems.org'
gem 'u-case', '~> 4.2.1'
gem 'pry-byebug'
gem 'awesome_print'
gem 'activesupport', require: 'active_support/all'
end
class ValidateBasicPeriod < Micro::Case
attributes :input
def call!
validation_errors = []
input[:periods].each_with_index do |p, idx|
validation_errors << "start_at is not present ad #{idx +1 }º period" if p[:start_at].blank?
validation_errors << "end_at is not present #{idx +1 }º" if p[:end_at].blank?
end
if validation_errors.present?
Failure :invalid_period_params, result: { errors: validation_errors }
else
Success()
end
end
end
class ValidateWeightPeriodDistribution < Micro::Case
attributes :input
def call!
presence_inputs
.then(apply(:sum_of_periods))
end
private
def presence_inputs
validation_errors = []
input[:periods].each_with_index do |p, idx|
validation_errors << "value is not present ad #{idx +1 }º period" if p[:value].blank?
end
if validation_errors.present?
Failure :invalid_wight_period_params, result: { errors: validation_errors }
else
Success :presence_inputs
end
end
def sum_of_periods(input:, **)
sum = input[:periods].inject(0) {|sum, p| sum + p[:value] }
if sum == input[:value]
Success :sum_of_periods
else
Failure :invalid_sum_of_periods, result: { errors: ['invalid_sum_of_periods'] }
end
end
end
class ValidBasicGoal < Micro::Case
attributes :input
def call!
validate_goal_params
.then(apply(:normalize_params))
end
private
def validate_goal_params
validation_errors = []
validation_errors << 'reference_month is not present' if input[:reference_month].blank?
validation_errors << 'start_at is not present' if input[:start_at].blank?
validation_errors << 'end_at is not present' if input[:end_at].blank?
validation_errors << 'value is not present' if input[:value].blank?
validation_errors << 'periods is not present' if input[:periods].blank?
if validation_errors.present?
Failure :invalid_goal_params, result: { errors: validation_errors }
else
Success()
end
end
def normalize_params(input:, **)
new_input = {}
new_input[:start_at] = input[:start_at].to_date
new_input[:end_at] = input[:end_at].to_date
new_input[:value] = input[:value].to_f
new_input[:periods] = input[:periods].map do |p|
{
start_at: p[:start_at].to_date,
end_at: p[:end_at].to_date
}
end
Success result: new_input
rescue => ex
Failure :normalize_params, result: { errors: [ex.message] }
end
end
class LinearMonthDistribution < Micro::Case
attributes :start_at, :end_at, :value, :periods
def call!
Success result: { goal: { periods: period_with_distribution, start_at: start_at, end_at: end_at,value: value } }
rescue => ex
Failure :error_month_distribution, result: { errors: [ex.message] }
end
private
def day_value
@_day_value ||= begin
dv = value/(start_at..end_at).count
dv.round(2)
end
end
def period_with_distribution
new_periods = periods.dup
new_periods.each do |period|
period[:days] = (period[:start_at]..period[:end_at]).map do |day|
{
date: day,
value: day_value
}
end
end
new_periods
end
end
class PeriodDistribution < Micro::Case
attributes :start_at, :end_at, :value, :periods
def call!
Success result: { goal: { periods: period_with_distribution, start_at: start_at, end_at: end_at,value: value } }
rescue => ex
Failure :error_month_distribution, result: { errors: [ex.message] }
end
private
def day_value(start_at, end_at )
dv = value/(start_at..end_at).count
dv.round(2)
end
def period_with_distribution
new_periods = periods.dup
new_periods.each do |period|
dv= day_value(period[:start_at], period[:end_at])
period[:days] = (period[:start_at]..period[:end_at]).map do |day|
{
date: day,
value: dv
}
end
end
new_periods
end
end
class Persisted < Micro::Case
attributes :goal
def call!
Success result: {goal: goal}
end
end
goal_linear_input = {
reference_month: '11/2020',
start_at: '01/11/2020',
end_at: '30/11/2020',
value: 30000.00,
periods: [
{
start_at: '01/11/2020',
end_at: '15/11/2020'
},
{
start_at: '16/11/2020',
end_at: '30/11/2020'
}
]
}
goal_period_distribution_input = {
reference_month: '11/2020',
start_at: '01/11/2020',
end_at: '30/11/2020',
value: 30000.00,
periods: [
{
start_at: '01/11/2020',
end_at: '15/11/2020',
value: 20000.0
},
{
start_at: '16/11/2020',
end_at: '30/11/2020',
value: 10000.0
}
]
}
class GoalMonthLinearDistribution < Micro::Case
flow ValidBasicGoal,
ValidateBasicPeriod,
LinearMonthDistribution,
Persisted
end
a = GoalMonthLinearDistribution.call input: goal_linear_input
GoalPeriodDistribution = Micro::Cases.flow([ValidBasicGoal,ValidateBasicPeriod, ValidateWeightPeriodDistribution, PeriodDistribution, Persisted,])
b = GoalPeriodDistribution.call(input: goal_period_distribution_input)
goal_linear_input = {
reference_month: '11/2020',
start_at: '01/11/2020',
end_at: '30/11/2020',
value: 30000.00,
periods: [
{
end_at: '15/11/2020'
},
{
start_at: '16/11/2020'
}
]
}
c = GoalMonthLinearDistribution.call input: goal_linear_input
# [2] pry(main)> c
# => #<Failure (Micro::Case::Result) type=:normalize_params data={:errors=>["undefined method `to_date' for nil:NilClass\nDid you mean? to_d"]} transitions=2>
# Corretor seria: invalid_period_params do ValidateBasicPeriod
pry
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment