import java.util.*;
import java.time.LocalDate;
import java.text.NumberFormat;

public class Main {
    
public static void main(String[] args) {

    List<Venda> vendas = DadosMock.criarVendas();

    LocalDate dataInicio = LocalDate.of(2024, 1, 1);
    LocalDate dataFim = LocalDate.of(2024, 1, 31);

    KpiService kpiService = new KpiService(vendas, dataInicio, dataFim);
    RelatorioConsole relatorio = new RelatorioConsole(kpiService, dataInicio, dataFim);

    relatorio.gerar();
}

}


class Cliente {
    String nome;

    Cliente(String nome) {
        this.nome = nome;
    }
}

class Produto {
    String nome;
    double preco;

    Produto(String nome, double preco) {
        this.nome = nome;
        this.preco = preco;
    }
}

class Venda {
    Cliente cliente;
    Produto produto;
    int quantidade;
    LocalDate data;

    Venda(Cliente cliente, Produto produto, int quantidade, LocalDate data) {
        this.cliente = cliente;
        this.produto = produto;
        this.quantidade = quantidade;
        this.data = data;
    }

    double valorTotal() {
        return produto.preco * quantidade;
    }
}

class DadosMock {

    static List<Venda> criarVendas() {

        Cliente c1 = new Cliente("Cliente A");
        Cliente c2 = new Cliente("Cliente B");

        Produto p1 = new Produto("Açúcar Cristal", 120.00);
        Produto p2 = new Produto("Açúcar Refinado", 135.00);

        List<Venda> vendas = new ArrayList<>();

        vendas.add(new Venda(c1, p1, 10, LocalDate.of(2024, 1, 5)));
        vendas.add(new Venda(c1, p2, 5, LocalDate.of(2024, 1, 10)));
        vendas.add(new Venda(c2, p1, 8, LocalDate.of(2024, 1, 15)));
        vendas.add(new Venda(c2, p2, 12, LocalDate.of(2024, 1, 20)));

        return vendas;
    }
}

class KpiService {

    private List<Venda> vendasFiltradas;

    KpiService(List<Venda> vendas, LocalDate inicio, LocalDate fim) {
        this.vendasFiltradas = vendas.stream()
            .filter(v ->
                !v.data.isBefore(inicio) &&
                !v.data.isAfter(fim)
            )
            .toList();
    }

    double faturamentoTotal() {
        return vendasFiltradas.stream()
                .mapToDouble(Venda::valorTotal)
                .sum();
    }

    int quantidadeVendas() {
        return vendasFiltradas.size();
    }

    double ticketMedio() {
        if (quantidadeVendas() == 0) return 0;
        return faturamentoTotal() / quantidadeVendas();
    }

    Map<String, Double> faturamentoPorProdutoOrdenado() {
        return vendasFiltradas.stream()
            .collect(
                java.util.stream.Collectors.groupingBy(
                    v -> v.produto.nome,
                    java.util.stream.Collectors.summingDouble(Venda::valorTotal)
                )
            )
            .entrySet()
            .stream()
            .sorted(Map.Entry.<String, Double>comparingByValue().reversed())
            .collect(
                java.util.stream.Collectors.toMap(
                    Map.Entry::getKey,
                    Map.Entry::getValue,
                    (a, b) -> a,
                    LinkedHashMap::new
                )
            );
    }

    Map<String, Double> faturamentoPorClienteOrdenado() {
        return vendasFiltradas.stream()
            .collect(
                java.util.stream.Collectors.groupingBy(
                    v -> v.cliente.nome,
                    java.util.stream.Collectors.summingDouble(Venda::valorTotal)
                )
            )
            .entrySet()
            .stream()
            .sorted(Map.Entry.<String, Double>comparingByValue().reversed())
            .collect(
                java.util.stream.Collectors.toMap(
                    Map.Entry::getKey,
                    Map.Entry::getValue,
                    (a, b) -> a,
                    LinkedHashMap::new
                )
            );
    }
}


class RelatorioConsole {

    private KpiService service;
    private LocalDate inicio;
    private LocalDate fim;

    RelatorioConsole(KpiService service, LocalDate inicio, LocalDate fim) {
        this.service = service;
        this.inicio = inicio;
        this.fim = fim;
    }

    void gerar() {

        NumberFormat moeda = NumberFormat.getCurrencyInstance(new Locale("pt", "BR"));

        System.out.println("==============================================");
        System.out.println("        RELATÓRIO DE INDICADORES OPERACIONAIS");
        System.out.println("==============================================");
        System.out.println("Período analisado: " + inicio + " até " + fim);
        System.out.println();

        System.out.println("📌 RESUMO EXECUTIVO");
        System.out.println("----------------------------------------------");
        System.out.println("Faturamento total........: " + moeda.format(service.faturamentoTotal()));
        System.out.println("Quantidade de vendas.....: " + service.quantidadeVendas());
        System.out.println("Ticket médio.............: " + moeda.format(service.ticketMedio()));

        System.out.println("\n🏆 TOP PRODUTOS POR FATURAMENTO");
        System.out.println("----------------------------------------------");

        int posicao = 1;
        for (var entry : service.faturamentoPorProdutoOrdenado().entrySet()) {
            System.out.println(posicao + "º - " + entry.getKey()
                + " | " + moeda.format(entry.getValue()));
            posicao++;
        }

        System.out.println("\n🏆 TOP CLIENTES POR FATURAMENTO");
        System.out.println("----------------------------------------------");

        posicao = 1;
        for (var entry : service.faturamentoPorClienteOrdenado().entrySet()) {
            System.out.println(posicao + "º - " + entry.getKey()
                + " | " + moeda.format(entry.getValue()));
            posicao++;
        }

        System.out.println("\n==============================================");
        System.out.println("Relatório gerado automaticamente pelo sistema");
        System.out.println("==============================================");
    }
}

Embed on website

To embed this project on your website, copy the following code and paste it into your website's HTML: