'creating a class object array inside another object?

I've got these three classes

class Totalizavel 
    def retorna (qnt, valor)
        total = qnt * valor
        return total
    end
end

class Venda < Totalizavel
    def initialize (num, data, cliente, itens)
        @venda_num = num            #int
        @venda_data = data          #tipo Date
        @venda_cliente = cliente    #tipo Cliente
        @venda_itens = itens        #tipo Item_Venda
    end

    def get_num
        return @venda_num
    end

    def get_data
        return @venda_data
    end

    def get_cliente
        return @venda_cliente
    end

    def get_item
        return @venda_itens
    end
    
    def set_num (numero)
        @venda_num = numero
    end

    def set_data (data)
        @venda_data = data
    end

    def set_cliente (cliente)
        @venda_cliente = cliente
    end

    def set_item (item)
        @venda_itens = item
    end
end

class ItemVenda < Totalizavel
    def initialize (produto, valor, quantidade)
        @item_produto = produto
        @item_valor = valor
        @item_qnt = quantidade
    end
    
    def get_produto
        return @item_produto
    end
    
    def get_valor
        return @item_valor
    end
    
    def get_qnt
        return @item_qnt
    end
    
    def set_produto (produto)
        @item_produto = produto
    end
    
    def set_valor (valor)
        @item_valor = valor
    end
    
    def set_qnt (qnt)
        @item_qnt = qnt
    end
    
end

And this attribute "@venda_itens" should to be an array of "ItemVenda", how is the best way to initialize it ? I've tried creating an auxiliar array and then "pass" it to the class like this:

remind that's only part of the code

def manipvendas
  while true
    puts "\n1- Add sell"
    puts "2- show sells"
    puts "0- get back to previous menu"
    print "Insert the desired option: "
    escolha = gets.chomp
    return if escolha == "0"

    if escolha == "1" #add sell
      print "\nInsert the number: "
      numvend = gets.chomp
      numvend = numvend.to_i
      print "\nInsert the date (Year, month, day): "
      ano = gets.chomp
      mes = gets.chomp
      dia = gets.chomp
      data = Time.new(ano.to_i, mes.to_i, dia.to_i)
      print "\nInsert the client: "
      clientenum = gets.chomp
      vendai = Venda.new(numvend,data,clientenum,selecproduto)
      @vendas.push(vendai)
    end

    if escolha == "2" #show sells
      if @vendas.size == 0
        puts "\nThere are no sells"
      else
      puts "\nPrinting sells database: \n\n"
        i = 0
        for a in [email protected] do
          puts "Code: " + @vendas[i].get_num.to_s
          puts "Date: " + @vendas[i].get_data.day.to_s + "/" + @vendas[i].get_data.month.to_s + "/" + @vendas[i].get_data.year.to_s + "\n"
          puts "Client: " + @vendas[i].get_cliente.to_s
          puts "Itens: "
          if @vendas[i].get_item.size == 0
            puts "\nThere are no itens"
          else
            j = 0
          for a in 1..@vendas[i].get_item.size do
            puts "Number: " +  @vendas[i].get_item[j].get_produto.to_s
            puts "Unity value: " + @vendas[i].get_item[j].get_valor.to_s
            puts "Sold: " + @vendas[i].get_item[j].get_qnt.to_s
            puts "Total value: " + @vendas[i].get_item[j].retorna(@vendas[i].get_item[j].get_valor.to_f, @vendas[i].get_item[j].get_qnt.to_i).to_s
            j = j+1
          end
          end
         i = i+1
        end
        end
    end
      

  end
end

def selecproduto
  while true
    @itemvenda.clear
    puts "\nInsert the product number: "
    print "Insert -1 to return: "
    produtonum = gets.chomp
    return if produtonum == "-1"
    produtonum = produtonum.to_i
    print "\nInsert the amount sold: "
    produtoqnt = gets.chomp
    produtoqnt = produtoqnt.to_i
    valor = produtoqnt.to_i
    vendaitem = ItemVenda.new(produtonum, @produtos[produtonum].get_valor, valor)
    @itemvenda.push(vendaitem)
    return vendaitem
  end
end

It's returning correctly until I try to add another "product", when I do this then select to show the registered sells, it returns me the amount of sells I created but with the parameters of the last sell multiplied for the number os registered sells

What's wrong with my code ?



Solution 1:[1]

We can refactor some methods. Let's go!

When you instantiate a new object Venda, you can pass the array of ItemVenda, like this:

itens = [item1, item2, item3]
cliente = Cliente.new("João", "[email protected]")
venda = Venda.new(1, DateTime.now, cliente, itens)
venda.total(itens)
require 'date'

class Venda
  attr_accessor :num, :data, :cliente, :itens

  def initialize(num, data, cliente, itens)
    @num = num            #int
    @total = total        #int
    @data = data          #tipo Date
    @cliente = cliente    #tipo Cliente
    @itens = itens        #tipo Item_Venda
  end

  def total(itens)
    itens.map { |item| item.quantidade * item.valor }.sum
  end

  def add_item(item)
    @itens << item
  end
end

class ItemVenda < Venda
  attr_accessor :produto, :valor, :quantidade

  def initialize (produto, valor, quantidade)
    @produto = produto
    @valor = valor
    @quantidade = quantidade
  end
end

class Cliente
  attr_accessor :nome, :email
  
  def initialize(nome, email)
    @nome = nome
    @email = email
  end
end

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 luiz-m-affonso