Skip to content

Instantly share code, notes, and snippets.

@mrbongiolo
Last active December 4, 2020 13:54
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mrbongiolo/10d4c3399c0623e6a466ec9d39ed12a2 to your computer and use it in GitHub Desktop.
Save mrbongiolo/10d4c3399c0623e6a466ec9d39ed12a2 to your computer and use it in GitHub Desktop.
Using u-case to process a json file
# frozen_string_literal: true
module StocksGames
class SendWrapped2020Emails < Micro::Case::Strict
attribute :file_path
def call!
parse_json
.then(apply(:group_by_user))
.then(apply(:collect_name_and_valid_wallets))
end
private
def parse_json
file = File.read(file_path)
result = JSON.parse(file)
Success :parse_json, result: { list: result }
end
def group_by_user(list:, **)
Success :group_by_user, result: {
list: list.group_by { |record| record['User → Email'] }
}
end
def collect_name_and_valid_wallets(list:, **)
result = list.each_with_object({}) do |(email, records), acum|
CollectValidWallets.call(records: records).on_success do |(data, _)|
acum[email] = { 'name' => records.first['User → Name'], 'wallets' => data[:wallets] }
end
end
Success :collect_name_and_valid_wallets, result: { list: result }
end
class CollectValidWallets < Micro::Case::Strict
attribute :records
def call!
group_by_category
.then(apply(:process_wallets))
end
private
def group_by_category
Success :group_by_category, result: {
wallets: records.group_by { |record| record['Category'] }
}
end
def process_wallets(wallets:, **)
result = wallets.each_with_object({}) do |(category, items), wallet|
ProcessWallet.call(items: items).on_success { |(data, _)| wallet[category] = data }
end
return Failure :no_valid_wallets if result.empty?
Success :process_wallets, result: { wallets: result }
end
end
class ProcessWallet < Micro::Case::Strict
attribute :items
def call!
normalize_items
.then(apply(:calculate_rate))
.then(apply(:calculate_quota))
.then(apply(:format_response))
end
private
INITIAL_QUOTA = 10_000.to_d
private_constant :INITIAL_QUOTA
def normalize_items
result = items.map do |item|
{
'weight' => Yubb::Types::Params::FiniteDecimal[item['Weight']],
'ticker' => item['Stock Ticker']
}
end
Success :normalize_items, result: { items: result }
end
def calculate_rate(items:)
rate = items.sum do |item|
result = CalculateItemRate.call(item)
return Failure :calculate_rate if result.failure?
result[:rate]
end
Success :all, result: { rate: rate }
end
def calculate_quota(rate:, **)
Success :calculate_quota, result: { quota: (INITIAL_QUOTA * (1 + rate)).truncate(8) }
end
def format_response(rate:, quota:, items:, **)
Success :format_response, result: { rate: rate, quota: quota, items: items }
end
end
class CalculateItemRate < Micro::Case::Safe
attribute :weight
attribute :ticker
def call!
find_stock!
.then(apply(:find_initial_price!))
.then(apply(:find_final_price!))
.then(apply(:calculate_rate))
end
private
INITIAL_DATE = '2020-04-13'
FINAL_DATE = '2020-11-30'
private_constant :INITIAL_DATE, :FINAL_DATE
def find_stock!
Success :find_stock, result: {
stock: Rails.cache.fetch(cache_key) { ::Stock.find_by!(ticker: ticker) }
}
end
def find_initial_price!(stock:, **)
Success :find_initial_price, result: {
initial_price: Rails.cache.fetch(cache_key) { stock.historic_prices.find_by!(closed_on: INITIAL_DATE).amount }
}
end
def find_final_price!(stock:, **)
Success :find_final_price, result: {
final_price: Rails.cache.fetch(cache_key) { stock.historic_prices.find_by!(closed_on: FINAL_DATE).amount }
}
end
def calculate_rate(weight:, initial_price:, final_price:, **)
Success :calculate_rate, result: {
rate: weight * ((final_price / initial_price) - 1).truncate(8)
}
end
def cache_key
[self.class.name, caller_locations(1..1).first.label, ticker, Time.zone.today.to_s, self.class.file_version]
end
# Class Methods
class << self
attr_reader :file_version
def file_version!
@file_version = checksum(File.read(File.expand_path(__FILE__)))
end
def checksum(string)
return if string.blank?
Digest::SHA1.hexdigest(string)
end
end
file_version!
end
end
end
[
{"Category":"day_trade","Logged At":"2020-04-12T15:00:00","User → Name":"user01","Weight":0.100000,"ID":2221366,"User → Email":"user01@email.com","Stock Ticker":"SAPR11","Stocks Game Wallet → Category":0,"Stocks Game Wallet ID":296},
{"Category":"day_trade","Logged At":"2020-04-12T15:00:00","User → Name":"user01","Weight":0.100000,"ID":2221370,"User → Email":"user01@email.com","Stock Ticker":"CAML3","Stocks Game Wallet → Category":0,"Stocks Game Wallet ID":296},
{"Category":"day_trade","Logged At":"2020-04-12T15:00:00","User → Name":"user01","Weight":0.150000,"ID":2221363,"User → Email":"user01@email.com","Stock Ticker":"SQIA3","Stocks Game Wallet → Category":0,"Stocks Game Wallet ID":296},
{"Category":"day_trade","Logged At":"2020-04-12T15:00:00","User → Name":"user01","Weight":0.100000,"ID":2221365,"User → Email":"user01@email.com","Stock Ticker":"EZTC3","Stocks Game Wallet → Category":0,"Stocks Game Wallet ID":296},
{"Category":"day_trade","Logged At":"2020-04-12T15:00:00","User → Name":"user01","Weight":0.100000,"ID":2221369,"User → Email":"user01@email.com","Stock Ticker":"VVAR3","Stocks Game Wallet → Category":0,"Stocks Game Wallet ID":296},
{"Category":"day_trade","Logged At":"2020-04-12T15:00:00","User → Name":"user01","Weight":0.150000,"ID":2221368,"User → Email":"user01@email.com","Stock Ticker":"MILS3","Stocks Game Wallet → Category":0,"Stocks Game Wallet ID":296},
{"Category":"day_trade","Logged At":"2020-04-12T15:00:00","User → Name":"user01","Weight":0.100000,"ID":2221371,"User → Email":"user01@email.com","Stock Ticker":"PETR3","Stocks Game Wallet → Category":0,"Stocks Game Wallet ID":296},
{"Category":"day_trade","Logged At":"2020-04-12T15:00:00","User → Name":"user01","Weight":0.100000,"ID":2221364,"User → Email":"user01@email.com","Stock Ticker":"RLOG3","Stocks Game Wallet → Category":0,"Stocks Game Wallet ID":296},
{"Category":"day_trade","Logged At":"2020-04-12T15:00:00","User → Name":"user01","Weight":0.100000,"ID":2221367,"User → Email":"user01@email.com","Stock Ticker":"ABEV3","Stocks Game Wallet → Category":0,"Stocks Game Wallet ID":296},
{"Category":"day_trade","Logged At":"2020-04-12T15:00:00","User → Name":"user02","Weight":0.100000,"ID":2221808,"User → Email":"user02@email.com","Stock Ticker":"ALPA3","Stocks Game Wallet → Category":0,"Stocks Game Wallet ID":409},
{"Category":"day_trade","Logged At":"2020-04-12T15:00:00","User → Name":"user02","Weight":0.100000,"ID":2221811,"User → Email":"user02@email.com","Stock Ticker":"BBDC3","Stocks Game Wallet → Category":0,"Stocks Game Wallet ID":409},
{"Category":"day_trade","Logged At":"2020-04-12T15:00:00","User → Name":"user02","Weight":0.250000,"ID":2221806,"User → Email":"user02@email.com","Stock Ticker":"ITSA3","Stocks Game Wallet → Category":0,"Stocks Game Wallet ID":409},
{"Category":"day_trade","Logged At":"2020-04-12T15:00:00","User → Name":"user02","Weight":0.100000,"ID":2221812,"User → Email":"user02@email.com","Stock Ticker":"BIDI11","Stocks Game Wallet → Category":0,"Stocks Game Wallet ID":409},
{"Category":"day_trade","Logged At":"2020-04-12T15:00:00","User → Name":"user02","Weight":0.250000,"ID":2221807,"User → Email":"user02@email.com","Stock Ticker":"ITSA4","Stocks Game Wallet → Category":0,"Stocks Game Wallet ID":409},
{"Category":"day_trade","Logged At":"2020-04-12T15:00:00","User → Name":"user02","Weight":0.100000,"ID":2221810,"User → Email":"user02@email.com","Stock Ticker":"EGIE3","Stocks Game Wallet → Category":0,"Stocks Game Wallet ID":409},
{"Category":"day_trade","Logged At":"2020-04-12T15:00:00","User → Name":"user02","Weight":0.100000,"ID":2221809,"User → Email":"user02@email.com","Stock Ticker":"ABEV3","Stocks Game Wallet → Category":0,"Stocks Game Wallet ID":409},
{"Category":"day_trade","Logged At":"2020-04-12T15:00:00","User → Name":"user03","Weight":0.100000,"ID":2221270,"User → Email":"user03@email.com","Stock Ticker":"GFSA3","Stocks Game Wallet → Category":0,"Stocks Game Wallet ID":265},
{"Category":"day_trade","Logged At":"2020-04-12T15:00:00","User → Name":"user03","Weight":0.100000,"ID":2221266,"User → Email":"user03@email.com","Stock Ticker":"BRFS3","Stocks Game Wallet → Category":0,"Stocks Game Wallet ID":265},
{"Category":"day_trade","Logged At":"2020-04-12T15:00:00","User → Name":"user03","Weight":0.200000,"ID":2221269,"User → Email":"user03@email.com","Stock Ticker":"B3SA3","Stocks Game Wallet → Category":0,"Stocks Game Wallet ID":265},
{"Category":"day_trade","Logged At":"2020-04-12T15:00:00","User → Name":"user03","Weight":0.200000,"ID":2221267,"User → Email":"user03@email.com","Stock Ticker":"BRKM5","Stocks Game Wallet → Category":0,"Stocks Game Wallet ID":265},
{"Category":"day_trade","Logged At":"2020-04-12T15:00:00","User → Name":"user03","Weight":0.200000,"ID":2221271,"User → Email":"user03@email.com","Stock Ticker":"ITSA3","Stocks Game Wallet → Category":0,"Stocks Game Wallet ID":265},
{"Category":"day_trade","Logged At":"2020-04-12T15:00:00","User → Name":"user03","Weight":0.200000,"ID":2221268,"User → Email":"user03@email.com","Stock Ticker":"MGLU3","Stocks Game Wallet → Category":0,"Stocks Game Wallet ID":265},
{"Category":"day_trade","Logged At":"2020-04-12T15:00:00","User → Name":"user04","Weight":0.200000,"ID":2220493,"User → Email":"user04@email.com","Stock Ticker":"POMO4","Stocks Game Wallet → Category":0,"Stocks Game Wallet ID":5},
{"Category":"day_trade","Logged At":"2020-04-12T15:00:00","User → Name":"user04","Weight":0.100000,"ID":2220488,"User → Email":"user04@email.com","Stock Ticker":"TAEE4","Stocks Game Wallet → Category":0,"Stocks Game Wallet ID":5},
{"Category":"day_trade","Logged At":"2020-04-12T15:00:00","User → Name":"user04","Weight":0.100000,"ID":2220490,"User → Email":"user04@email.com","Stock Ticker":"CPLE3","Stocks Game Wallet → Category":0,"Stocks Game Wallet ID":5},
{"Category":"day_trade","Logged At":"2020-04-12T15:00:00","User → Name":"user04","Weight":0.100000,"ID":2220495,"User → Email":"user04@email.com","Stock Ticker":"LEVE3","Stocks Game Wallet → Category":0,"Stocks Game Wallet ID":5},
{"Category":"day_trade","Logged At":"2020-04-12T15:00:00","User → Name":"user04","Weight":0.100000,"ID":2220491,"User → Email":"user04@email.com","Stock Ticker":"ENGI4","Stocks Game Wallet → Category":0,"Stocks Game Wallet ID":5},
{"Category":"day_trade","Logged At":"2020-04-12T15:00:00","User → Name":"user04","Weight":0.200000,"ID":2220494,"User → Email":"user04@email.com","Stock Ticker":"VVAR3","Stocks Game Wallet → Category":0,"Stocks Game Wallet ID":5},
{"Category":"day_trade","Logged At":"2020-04-12T15:00:00","User → Name":"user04","Weight":0.100000,"ID":2220489,"User → Email":"user04@email.com","Stock Ticker":"CGAS5","Stocks Game Wallet → Category":0,"Stocks Game Wallet ID":5},
{"Category":"day_trade","Logged At":"2020-04-12T15:00:00","User → Name":"user04","Weight":0.100000,"ID":2220492,"User → Email":"user04@email.com","Stock Ticker":"ITSA4","Stocks Game Wallet → Category":0,"Stocks Game Wallet ID":5},
{"Category":"day_trade","Logged At":"2020-04-12T15:00:00","User → Name":"user05","Weight":0.100000,"ID":2221694,"User → Email":"user05@email.com","Stock Ticker":"PETR4","Stocks Game Wallet → Category":0,"Stocks Game Wallet ID":374},
{"Category":"day_trade","Logged At":"2020-04-12T15:00:00","User → Name":"user05","Weight":0.100000,"ID":2221696,"User → Email":"user05@email.com","Stock Ticker":"JBSS3","Stocks Game Wallet → Category":0,"Stocks Game Wallet ID":374},
{"Category":"day_trade","Logged At":"2020-04-12T15:00:00","User → Name":"user05","Weight":0.100000,"ID":2221699,"User → Email":"user05@email.com","Stock Ticker":"CYRE3","Stocks Game Wallet → Category":0,"Stocks Game Wallet ID":374},
{"Category":"day_trade","Logged At":"2020-04-12T15:00:00","User → Name":"user05","Weight":0.100000,"ID":2221693,"User → Email":"user05@email.com","Stock Ticker":"VALE3","Stocks Game Wallet → Category":0,"Stocks Game Wallet ID":374},
{"Category":"day_trade","Logged At":"2020-04-12T15:00:00","User → Name":"user05","Weight":0.100000,"ID":2221700,"User → Email":"user05@email.com","Stock Ticker":"IGTA3","Stocks Game Wallet → Category":0,"Stocks Game Wallet ID":374},
{"Category":"day_trade","Logged At":"2020-04-12T15:00:00","User → Name":"user05","Weight":0.100000,"ID":2221702,"User → Email":"user05@email.com","Stock Ticker":"PCAR4","Stocks Game Wallet → Category":0,"Stocks Game Wallet ID":374},
{"Category":"day_trade","Logged At":"2020-04-12T15:00:00","User → Name":"user05","Weight":0.100000,"ID":2221695,"User → Email":"user05@email.com","Stock Ticker":"MGLU3","Stocks Game Wallet → Category":0,"Stocks Game Wallet ID":374},
{"Category":"day_trade","Logged At":"2020-04-12T15:00:00","User → Name":"user05","Weight":0.100000,"ID":2221698,"User → Email":"user05@email.com","Stock Ticker":"B3SA3","Stocks Game Wallet → Category":0,"Stocks Game Wallet ID":374},
{"Category":"day_trade","Logged At":"2020-04-12T15:00:00","User → Name":"user05","Weight":0.100000,"ID":2221697,"User → Email":"user05@email.com","Stock Ticker":"BBAS3","Stocks Game Wallet → Category":0,"Stocks Game Wallet ID":374},
{"Category":"day_trade","Logged At":"2020-04-12T15:00:00","User → Name":"user05","Weight":0.100000,"ID":2221701,"User → Email":"user05@email.com","Stock Ticker":"IRBR3","Stocks Game Wallet → Category":0,"Stocks Game Wallet ID":374},
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment