diff --git a/Gemfile b/Gemfile index 4f1a83c7..f9e640e9 100644 --- a/Gemfile +++ b/Gemfile @@ -53,6 +53,9 @@ gem "bcrypt", "~> 3.1" gem "jwt" gem "jbuilder" +# Banco de Chile Uploads +gem "spreadsheet" + # OAuth & API Security gem "doorkeeper" gem "rack-attack", "~> 6.6" diff --git a/Gemfile.lock b/Gemfile.lock index cacdf57a..13996235 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -501,6 +501,7 @@ GEM sorbet-runtime (>= 0.5.10782) ruby-lsp-rails (0.4.6) ruby-lsp (>= 0.24.0, < 0.25.0) + ruby-ole (1.2.13.1) ruby-openai (8.1.0) event_stream_parser (>= 0.3.0, < 2.0.0) faraday (>= 1) @@ -552,6 +553,10 @@ GEM activesupport (>= 5.2.0) smart_properties (1.17.0) sorbet-runtime (0.5.12163) + spreadsheet (1.3.4) + bigdecimal + logger + ruby-ole stackprof (0.2.27) stimulus-rails (1.3.4) railties (>= 6.0.0) @@ -680,6 +685,7 @@ DEPENDENCIES sidekiq-cron simplecov skylight + spreadsheet stackprof stimulus-rails stripe diff --git a/app/controllers/import/uploads_controller.rb b/app/controllers/import/uploads_controller.rb index e51b5278..f4739b68 100644 --- a/app/controllers/import/uploads_controller.rb +++ b/app/controllers/import/uploads_controller.rb @@ -33,7 +33,9 @@ class Import::UploadsController < ApplicationController end def csv_str - @csv_str ||= upload_params[:csv_file]&.read || upload_params[:raw_file_str] + @csv_str ||= BancoChileParser.new(upload_params[:csv_file]).parse || + upload_params[:csv_file]&.read || + upload_params[:raw_file_str] end def csv_valid?(str) diff --git a/app/services/banco_chile_parser.rb b/app/services/banco_chile_parser.rb new file mode 100644 index 00000000..0b863a86 --- /dev/null +++ b/app/services/banco_chile_parser.rb @@ -0,0 +1,106 @@ +class BancoChileParser + attr_reader :sheet + def initialize(file) + @file = file + end + + def parse + @sheet = Spreadsheet.open(@file).worksheet(0) + parse_sheet + rescue => e + nil + end + + private + + def parse_sheet + return parse_cuenta_corriente if cuenta_corriente? + + return parse_tarjeta_credito_clp if tarjeta_de_credito_clp? + + parse_tarjeta_credito_usd if tarjeta_de_credito_usd? + end + + def cuenta_corriente? + @sheet[9,1] == "Cuenta:" + end + + def tarjeta_de_credito_clp? + @sheet[9,1] == "Tipo de Tarjeta:" && @sheet[17,8] == "Monto ($)" + end + + def tarjeta_de_credito_usd? + @sheet[9,1] == "Tipo de Tarjeta:" && @sheet[17,8] == "Monto (USD)" + end + + def parse_cuenta_corriente + csv_string = "date*,name,amount*,currency\n" + reached_description = false + @sheet.rows.each_with_index do |row, row_index| + if row[2] == "Descripción" + reached_description = true + next + end + next unless reached_description + next if row[2].blank? + # date + d,m,y = row[1].split("/") + csv_string << [m,d,y].join("/").concat(",") + # name + csv_string << row[2].concat(",") + # amount + csv_string << row[4].to_s.concat(",") if row[4].to_s.present? + csv_string << "-#{row[5]}," if row[5].to_s.present? + # currency + csv_string << "CLP\n" + end + csv_string + end + + def parse_tarjeta_credito_clp + csv_string = "date*,name,amount*,currency\n" + reached_description = false + @sheet.rows.each_with_index do |row, row_index| + if row[4] == "Descripción" + reached_description = true + next + end + next unless reached_description + next if row[2].blank? + # date + d,m,y = row[1].split("/") + csv_string << [m,d,y].join("/").concat(",") + # name + csv_string << row[4].concat(",") + # amount + csv_string << row[10].to_s.concat(",") if row[10].to_s.present? + csv_string << "-#{row[11]}," if row[11].to_s.present? + # currency + csv_string << "CLP\n" + end + csv_string + end + + def parse_tarjeta_credito_usd + csv_string = "date*,name,amount*,currency\n" + reached_description = false + @sheet.rows.each_with_index do |row, row_index| + if row[4] == "Descripción" + reached_description = true + next + end + next unless reached_description + next if row[2].blank? + # date + d,m,y = row[1].split("/") + csv_string << [m,d,y].join("/").concat(",") + # name + csv_string << row[4].concat(",") + # amount + csv_string << row[8].to_s.concat(",") if row[8].to_s.present? + # currency + csv_string << "USD\n" + end + csv_string + end +end \ No newline at end of file