# frozen_string_literal: true module MontoEscrito class Decorador def initialize(numero) raise ArgumentError if (numero >= 1_000_000_000_000_000_000_000_000) || numero.negative? @numero = numero end def to_s(format = :integer) if format == :integer @monto_escrito ||= calcular_monto_escrito(@numero) else centavos = (@numero - @numero.floor).round(2) * 100 @numero = @numero.floor @monto_escrito ||= if format == :short "#{calcular_monto_escrito(@numero)} con #{centavos.to_i}/100" else "#{calcular_monto_escrito(@numero)} con #{calcular_monto_escrito(centavos)}" end end end private def calcular_monto_escrito(numero) if casos_especiales[numero] monto_escrito = casos_especiales[numero] else monto_escrito = '' casos.each do |caso, detalles| next unless numero >= caso valor = (numero.to_i / detalles[:divisor]) * detalles[:multiplicador_primario] monto_escrito += calcular_monto_escrito(valor) + detalles[:sufijo] numero -= valor * detalles[:multiplicador_secundario] monto_escrito += detalles[:continuacion] if numero.positive? end end monto_escrito end def casos_especiales { 0 => 'cero', 1 => 'un', 2 => 'dos', 3 => 'tres', 4 => 'cuatro', 5 => 'cinco', 6 => 'seis', 7 => 'siete', 8 => 'ocho', 9 => 'nueve', 10 => 'diez', 11 => 'once', 12 => 'doce', 13 => 'trece', 14 => 'catorce', 15 => 'quince', 16 => 'dieciséis', 17 => 'diecisiete', 18 => 'dieciocho', 19 => 'diecinueve', 21 => 'veintiún', 22 => 'veintidós', 23 => 'veintitrés', 24 => 'veinticuatro', 25 => 'veinticinco', 26 => 'veintiséis', 27 => 'veintisiete', 28 => 'veintiocho', 29 => 'veintinueve', 10 => 'diez', 20 => 'veinte', 30 => 'treinta', 40 => 'cuarenta', 50 => 'cincuenta', 60 => 'sesenta', 70 => 'setenta', 80 => 'ochenta', 90 => 'noventa', 100 => 'cien', 200 => 'doscientos', 300 => 'trescientos', 400 => 'cuatrocientos', 500 => 'quinientos', 600 => 'seiscientos', 700 => 'setecientos', 800 => 'ochocientos', 900 => 'novecientos' } end def casos { 2_000_000_000_000_000_000 => { divisor: 1_000_000_000_000_000_000, multiplicador_primario: 1, multiplicador_secundario: 1_000_000_000_000_000_000, sufijo: ' trillones', continuacion: ' ' }, 1_000_000_000_000_000_000 => { divisor: 1_000_000_000_000_000_000, multiplicador_primario: 1, multiplicador_secundario: 1_000_000_000_000_000_000, sufijo: ' trillón', continuacion: ' ' }, 2_000_000_000_000 => { divisor: 1_000_000_000_000, multiplicador_primario: 1, multiplicador_secundario: 1_000_000_000_000, sufijo: ' billones', continuacion: ' ' }, 1_000_000_000_000 => { divisor: 1_000_000_000_000, multiplicador_primario: 1, multiplicador_secundario: 1_000_000_000_000, sufijo: ' billón', continuacion: ' ' }, 2_000_000 => { divisor: 1_000_000, multiplicador_primario: 1, multiplicador_secundario: 1_000_000, sufijo: ' millones', continuacion: ' ' }, 1_000_000 => { divisor: 1_000_000, multiplicador_primario: 1, multiplicador_secundario: 1_000_000, sufijo: ' millón', continuacion: ' ' }, 1_000 => { divisor: 1_000, multiplicador_primario: 1, multiplicador_secundario: 1_000, sufijo: ' mil', continuacion: ' ' }, 200 => { divisor: 100, multiplicador_primario: 100, multiplicador_secundario: 1, sufijo: '', continuacion: ' ' }, 100 => { divisor: 100, multiplicador_primario: 100, multiplicador_secundario: 1, sufijo: 'to', continuacion: ' ' }, 30 => { divisor: 10, multiplicador_primario: 10, multiplicador_secundario: 1, sufijo: '', continuacion: ' y ' }, 1 => { divisor: 1, multiplicador_primario: 1, multiplicador_secundario: 1, sufijo: '', continuacion: '' } } end end end