Skip to content

Instantly share code, notes, and snippets.

@dev2me
Last active June 17, 2023 20:38
Show Gist options
  • Save dev2me/6b98333116154f1896e86af29c92d86a to your computer and use it in GitHub Desktop.
Save dev2me/6b98333116154f1896e86af29c92d86a to your computer and use it in GitHub Desktop.
A module Bank Transfer
class BankTransfer
# Parser Module
module Parser
# Active Record Data
class ActiveRecordData
def initialize(data, config)
@data = data
@config = config
end
def operation
@config.operation_types[bank_operation]
end
def beneficiary_name
I18n.t(
'services.bank_transfer.data_parser.beneficiary_name',
{ locale: :es, name: seller_full_name }
)
end
def source_account
@config.source_account
end
def target_account
accout_by_operation(bank_operation)
end
def transfer_ammount
(seller_payout_amount.to_f * 100).to_i
end
def reference_number
transfer_ammount
end
def transfer_concept
I18n.t(
'services.bank_transfer.data_parser.transfer_concept',
{ locale: :es, date: day_month_date }
)
end
def iva
' '
end
def target_email
@data.seller.email
end
def target_message
I18n.t(
'services.bank_transfer.data_parser.target_message',
{ locale: :es, product_name: product_name }
)
end
def pay_date
Time.zone.now.strftime('%d%m%Y')
end
private
def accout_by_operation(type)
if %i[own_account_transfer third_party_transfer].include?(type)
account_number
elsif %i[spei tef].include?(type)
account_code
end
end
def bank_operation
if local_bank_transfer? || local_bank_code?
:third_party_transfer
else
:spei
end
end
def product_name
@data.product.name.gsub(/[^0-9A-Za-z' ']/, '')
end
def seller_payout_amount
(@data.sale_amount.to_f * (100 - @data.order_product.commission_percentage) / 100) - @data.restauration_cost
end
def day_month_date
I18n.l(@data.created_at, format: :day_month, locale: :es)
end
def local_bank_transfer?
account_bank.downcase.to_sym == @config.bank
end
def local_bank_code?
account_code.first(3) == @config.bank_prefix
end
def seller_full_name
@data.seller.seller.find_by(is_active: true).full_name
end
def account_number
@data.seller.seller.find_by(is_active: true).account_number
end
def account_code
@data.seller.seller.find_by(is_active: true).code
end
def account_bank
@data.seller.seller.find_by(is_active: true).bank
end
end
end
end
class BankTransfer
include FileWritter
include DataFormatter
def initialize(bank: :banorte)
@bank = bank
end
def generate(orders)
data = format_data(orders, data_parser, config)
create_file(data)
end
private
def config
@config ||= Configuration.new(@bank)
end
def data_parser
Parser::ActiveRecordData
end
end
class BankTransfer
# Configuration
class Configuration
attr_accessor :bank
def initialize(bank)
@bank = bank
end
def attrs
send("#{@bank}_config")
end
def attr_keys
send("#{@bank}_config").keys
end
def bank_prefix
send("#{@bank}_prefix")
end
def operation_types
OPERATION_TYPES
end
def source_account
SOURCE_ACCOUNT
end
private
def banorte_config
BANORTE_CONFIG
end
def banorte_prefix
BANK_PREFIXES[:banorte]
end
BANORTE_CONFIG =
{
operation: {
source_attr: :config, max_length: 2, range: (1..2),
fill: ' ', fill_side: :rigth
},
beneficiary_name: {
source_attr: :data, max_length: 50, range: (3..52),
fill: ' ', fill_side: :rigth
},
source_account: {
source_attr: :config, max_length: 18, range: (53..70),
fill: '0', fill_side: :left
},
target_account: {
source_attr: :data, max_length: 18, range: (71..88),
fill: '0', fill_side: :left
},
transfer_ammount: {
source_attr: :data, max_length: 13, range: (89..101),
fill: '0', fill_side: :left
},
reference_number: {
source_attr: :config, max_length: 10, range: (102..111),
fill: '0', fill_side: :left
},
transfer_concept: {
source_attr: :config, max_length: 35, range: (112..146),
fill: ' ', fill_side: :rigth
},
iva: {
source_attr: :data, max_length: 29, range: (147..175),
fill: ' ', fill_side: :rigth
},
target_email: {
source_attr: :data, max_length: 60, range: (176..235),
fill: ' ', fill_side: :rigth
},
target_message: {
source_attr: :config, max_length: 100, range: (236..275),
fill: ' ', fill_side: :rigth
},
pay_date: {
source_attr: :config, max_length: 8, range: (276..283),
fill: ' ', fill_side: :rigth
}
}.freeze
BANK_PREFIXES =
{
banorte: '072'
}.freeze
OPERATION_TYPES =
{
own_account_transfer: '01',
third_party_transfer: '02',
spei: '04', tef: '05'
}.freeze
# NOTE: May be configurable from the Dashboard configurations
SOURCE_ACCOUNT = ENV['SOURCE_ACCOUNT']
end
end
class BankTransfer
# Formatter
module DataFormatter
def format_data(data_collection, data_parser, config)
row = []
data_collection.each do |data|
config.attr_keys.each do |key|
data_parsed = data_parser.new(data, config)
attr_data = data_parsed.send(key)
row << attr_format(attr_data, config.attrs[key])
end
row << "\n"
end
row.join
end
private
def attr_format(input, config)
if [:rigth].include? config[:fill_side]
input.to_s.ljust(config[:max_length], config[:fill])
elsif [:left].include? config[:fill_side]
input.to_s.rjust(config[:max_length], config[:fill])
end
end
end
end
class BankTransfer
# Temp File Writter
module FileWritter
def create_file(data)
tmp_file = Tempfile.new(file_name, encoding: 'UTF-8')
tmp_file.write(data)
tmp_file.rewind
tmp_file.read
ensure
tmp_file.unlink
end
private
def file_name
['tmp_file', '.txt']
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment