Last active
November 10, 2020 21:05
-
-
Save ricsdeol/b325bfc2e1d01591a7c383a71f97e654 to your computer and use it in GitHub Desktop.
Goals Ucase Exemple
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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