From 17fa48e923b6dcfd71c7b92bb661ed775f4635f1 Mon Sep 17 00:00:00 2001
From: Nico <nico.igramos@gmail.com>
Date: Sat, 7 Dec 2024 01:32:31 -0300
Subject: [PATCH] Tentando implementar retornar obra

---
 sources/Biblioteca.cpp          |  4 +--
 sources/Biblioteca.hpp          |  4 +--
 sources/ControladorObras.cpp    | 18 +++++++++--
 sources/ControladorUsuarios.cpp | 12 +++----
 sources/ControladorUsuarios.hpp |  3 +-
 sources/Emprestimo.cpp          | 29 +++++++++++++++--
 sources/Emprestimo.hpp          |  6 ++--
 sources/Obra.cpp                | 16 ++++++++--
 sources/Obra.hpp                |  2 +-
 sources/Usuario.cpp             | 22 +++++++------
 sources/Usuario.hpp             |  3 +-
 tdd/Makefile                    |  2 +-
 tdd/biblioteca-test.cpp         | 55 +++++++++++++++++++++++++++------
 13 files changed, 133 insertions(+), 43 deletions(-)

diff --git a/sources/Biblioteca.cpp b/sources/Biblioteca.cpp
index 2bf2b46..7ed1d20 100644
--- a/sources/Biblioteca.cpp
+++ b/sources/Biblioteca.cpp
@@ -9,10 +9,10 @@ Biblioteca& Biblioteca::getInstance() {
   return instancia;
 }
 
-ControladorObras Biblioteca::getContObras(){
+ControladorObras& Biblioteca::getContObras(){
   return ControladorObras::getInstance();
 }
 
-ControladorUsuarios Biblioteca::getContUsuarios(){
+ControladorUsuarios& Biblioteca::getContUsuarios(){
   return ControladorUsuarios::getInstance();
 }
diff --git a/sources/Biblioteca.hpp b/sources/Biblioteca.hpp
index 0b60e2e..76c559b 100644
--- a/sources/Biblioteca.hpp
+++ b/sources/Biblioteca.hpp
@@ -15,8 +15,8 @@ class Biblioteca {
 
     // Methods
     static Biblioteca& getInstance();
-    ControladorObras getContObras();
-    ControladorUsuarios getContUsuarios();
+    ControladorObras& getContObras();
+    ControladorUsuarios& getContUsuarios();
 };
 
 #endif // !__BIBLIOTECA__
diff --git a/sources/ControladorObras.cpp b/sources/ControladorObras.cpp
index dd307dd..67bb6d5 100644
--- a/sources/ControladorObras.cpp
+++ b/sources/ControladorObras.cpp
@@ -54,12 +54,26 @@ void ControladorObras::adicionarObra(DescricaoObra& descricao){
 }
 
 bool ControladorObras::solicitarEmprestimo(DescricaoObra& descricao){
+  auto it_obra = find_if(this->obras.begin(), this->obras.end(), [&descricao](Obra& d) {
+      return descricao.getTitulo() == d.getTitulo();
+      });
+
+  if (it_obra == this->obras.end()) {
+    return false;
+  }
 
-  return true;
+  return it_obra->emprestar();
 }
 
 
 bool ControladorObras::devolverEmprestimo(DescricaoObra& descricao){
+  auto it_obra = find_if(this->obras.begin(), this->obras.end(), [&descricao](Obra& d) {
+      return descricao.getTitulo() == d.getTitulo();
+      });
+
+  if (it_obra == this->obras.end()) {
+    return false;
+  }
 
-  return true;
+  return it_obra->devolver();
 }
diff --git a/sources/ControladorUsuarios.cpp b/sources/ControladorUsuarios.cpp
index d404692..fad1460 100644
--- a/sources/ControladorUsuarios.cpp
+++ b/sources/ControladorUsuarios.cpp
@@ -1,5 +1,6 @@
 #include <iostream>
 #include <algorithm>
+#include <chrono>
 
 #include "./ControladorUsuarios.hpp"
 #include "Usuario.hpp"
@@ -43,7 +44,7 @@ bool ControladorUsuarios::adicionarUsuario(string nome, string CPF, string ender
 }
 
 
-int ControladorUsuarios::registrarEmprestimo(string CPF, DescricaoObra& descricao){
+chrono::year_month_day ControladorUsuarios::registrarEmprestimo(string CPF, DescricaoObra& descricao){
 
   // Search for user
   auto it = find_if(usuarios.begin(), usuarios.end(), [CPF](Usuario& u) {
@@ -52,16 +53,15 @@ int ControladorUsuarios::registrarEmprestimo(string CPF, DescricaoObra& descrica
 
   if (it == usuarios.end()) {
     cerr << "> Erro: Usuario não encontrado" << endl;
-    return -1;
+    return chrono::year_month_day{chrono::year{0}, chrono::month{0}, chrono::day{0}};
   }
 
-  if (!it->emprestar(descricao)){
+  chrono::year_month_day dataDevolucao = it->emprestar(descricao);
+  if (0 == int(dataDevolucao.year()) && 0 == unsigned(dataDevolucao.month()) && 0 == unsigned(dataDevolucao.day())) {
     cerr << "> Erro: Falha ao realizar um emprestimo" << endl;
-    return -1;
   }
 
-  // Calcula data e retorna
-  return 0;
+  return dataDevolucao;
 }
 
 
diff --git a/sources/ControladorUsuarios.hpp b/sources/ControladorUsuarios.hpp
index bf00603..0a6af4f 100644
--- a/sources/ControladorUsuarios.hpp
+++ b/sources/ControladorUsuarios.hpp
@@ -1,6 +1,7 @@
 #ifndef __CONTROLADOR_USUARIOS__
 #define __CONTROLADOR_USUARIOS__
 
+#include <chrono>
 #include <string>
 #include <vector>
 
@@ -21,7 +22,7 @@ class ControladorUsuarios {
     // Methods
     static ControladorUsuarios& getInstance();
     bool adicionarUsuario(string nome, string CPF, string endereco, string telefone, string email);
-    int registrarEmprestimo(string CPF, DescricaoObra& descricao);
+    chrono::year_month_day registrarEmprestimo(string CPF, DescricaoObra& descricao);
     int retornarEmprestimo(string CPF, DescricaoObra& descricao);
     int recuperarMultas(string CPF);
     bool registrarMultaPaga(string CPF, int valor);
diff --git a/sources/Emprestimo.cpp b/sources/Emprestimo.cpp
index 6ba6c55..b967c78 100644
--- a/sources/Emprestimo.cpp
+++ b/sources/Emprestimo.cpp
@@ -1,23 +1,46 @@
 #include <iostream>
+#include <chrono>
 
 #include "./Emprestimo.hpp"
 #include "./DescricaoObra.hpp"
+#include "./ControladorObras.hpp"
 
 using namespace std;
 
 // Constructor
-Emprestimo::Emprestimo(int data, DescricaoObra& descricao)
-  : dataEmprestimo(data), descricao(descricao) {}
+Emprestimo::Emprestimo(DescricaoObra& descricao)
+  : descricao(descricao) {
+
+  const chrono::time_point now{chrono::system_clock::now()};
+  this->dataEmprestimo = {chrono::floor<chrono::days>(now)};
+
+  ControladorObras contObras = ControladorObras::getInstance();
+  if (!contObras.solicitarEmprestimo(descricao)) {
+    throw runtime_error("> Erro: obra nao existe");
+  }
+}
 
 void Emprestimo::mostraDetalhes() const {
-  cout << "Data: " << dataEmprestimo << endl;
+  cout << "Data de devolução: ";
+  cout << static_cast<unsigned>(this->dataEmprestimo.day()) << "/";
+  cout << static_cast<unsigned>(this->dataEmprestimo.month()) << "/";
+  cout << static_cast<int>(this->dataEmprestimo.year()) << endl;
   descricao.mostrarDetalhes();
 }
 
 
 // Methods
 void Emprestimo::removeEmprestimo(){
+  ControladorObras contObras = ControladorObras::getInstance();
+  if (!contObras.devolverEmprestimo(descricao)) {
+    throw runtime_error("> Erro: obra nao existe");
+  }
+}
 
+chrono::year_month_day Emprestimo::getDataDevolucao() {
+  chrono::sys_days emprestimoDias = this->dataEmprestimo;
+  chrono::sys_days devolucaoDias = emprestimoDias + chrono::days{3};
+  return chrono::year_month_day{devolucaoDias};
 }
 
 string Emprestimo::getDescricaoTitulo(){
diff --git a/sources/Emprestimo.hpp b/sources/Emprestimo.hpp
index f2185e4..2eace1d 100644
--- a/sources/Emprestimo.hpp
+++ b/sources/Emprestimo.hpp
@@ -1,22 +1,24 @@
 #ifndef __EMPRESTIMO__
 #define __EMPRESTIMO__
 
+#include <chrono>
 #include "./DescricaoObra.hpp"
 
 class Emprestimo {
   private:
-    int dataEmprestimo;
+    std::chrono::year_month_day dataEmprestimo;
     DescricaoObra &descricao;
 
   public:
     // Constructor
     Emprestimo();
-    Emprestimo(int data, DescricaoObra& descricao);
+    Emprestimo(DescricaoObra& descricao);
     void mostraDetalhes() const;
 
     // Methods
     void removeEmprestimo();
     string getDescricaoTitulo();
+    std::chrono::year_month_day getDataDevolucao();
 
 };
 
diff --git a/sources/Obra.cpp b/sources/Obra.cpp
index 3a967a1..cf399e8 100644
--- a/sources/Obra.cpp
+++ b/sources/Obra.cpp
@@ -17,11 +17,21 @@ void Obra::mostrarDetalhes() const {
 
 // Methods
 bool Obra::emprestar(){
-  return 0;
+  if (this->disponiveis > 0) {
+    this->disponiveis--;
+    return true;
+  }
+
+  return false;
 }
 
-void Obra::devolver(){
-  return;
+bool Obra::devolver(){
+  if (this->disponiveis == this->total) {
+    return false;
+  }
+
+  this->disponiveis++;
+  return true;
 }
 
 void Obra::adicionarObra(){
diff --git a/sources/Obra.hpp b/sources/Obra.hpp
index 672bc26..9ce0c8a 100644
--- a/sources/Obra.hpp
+++ b/sources/Obra.hpp
@@ -17,7 +17,7 @@ class Obra {
 
     // Methods
     bool emprestar();
-    void devolver();
+    bool devolver();
     void adicionarObra();
     string getTitulo();
     int getDisponiveis();
diff --git a/sources/Usuario.cpp b/sources/Usuario.cpp
index 96d91ac..4864d51 100644
--- a/sources/Usuario.cpp
+++ b/sources/Usuario.cpp
@@ -1,6 +1,7 @@
 #include <exception>
 #include <iostream>
 #include <algorithm>
+#include <chrono>
 
 #include "Emprestimo.hpp"
 #include "Usuario.hpp"
@@ -24,23 +25,24 @@ void Usuario::mostrarDetalhes() const {
 
 
 // Methods
-bool Usuario::emprestar(DescricaoObra& descricao){
+chrono::year_month_day Usuario::emprestar(DescricaoObra& descricao){
 
   // Check number of Borrowed works
   if (this->emprestimos->size() >= 3) {
-    cerr << "Erro: Usuario já possui três empresimos! Ignorando operação";
-    return false;
+    cerr << "> Erro: Usuario já possui três empresimos! Ignorando operação" << endl;
+    return chrono::year_month_day{chrono::year{0}, chrono::month{0}, chrono::day{0}};
   }
 
   // Create Emprestimo
   try {
-    Emprestimo emp(0, descricao);
+    Emprestimo emp(descricao);
+    this->emprestimos->push_back(emp);
+    emp.mostraDetalhes();
+    return emp.getDataDevolucao();
   } catch (const exception&) {
-    cerr << "Erro: Falha ao criar um emprestimo!" << endl;
-    return false;
+    cerr << "> Erro: Falha ao criar um emprestimo!" << endl;
+    return chrono::year_month_day{chrono::year{0}, chrono::month{0}, chrono::day{0}};
   }
-
-  return true;
 }
 
 bool Usuario::devolver(DescricaoObra& descricao){
@@ -51,14 +53,14 @@ bool Usuario::devolver(DescricaoObra& descricao){
     });
   
   if (emp_it == this->emprestimos->end()){
-    cerr << "Erro: Obra não encontrada nos emprestimos do Usuário!";
+    cerr << "Erro: Obra não encontrada nos emprestimos do Usuário!" << endl;
     return false;
   }
 
   emp_it->removeEmprestimo();
 
   // Remove work
-  //this->emprestimos->erase(emp_it);
+  // this->emprestimos->erase(emp_it);
 
   return true;
 }
diff --git a/sources/Usuario.hpp b/sources/Usuario.hpp
index 8447299..965f612 100644
--- a/sources/Usuario.hpp
+++ b/sources/Usuario.hpp
@@ -3,6 +3,7 @@
 
 #include <string>
 #include <vector>
+#include <chrono>
 
 #include "./DescricaoObra.hpp"
 #include "./Emprestimo.hpp"
@@ -27,7 +28,7 @@ class Usuario {
     void mostrarDetalhes() const;
 
     // Methods
-    bool emprestar(DescricaoObra& descricao);
+    std::chrono::year_month_day emprestar(DescricaoObra& descricao);
     bool devolver(DescricaoObra& descricao);
     int atualizarMulta(int valor);    // Increase fee
     string getCPF();
diff --git a/tdd/Makefile b/tdd/Makefile
index 9b4dd2f..c64d2a4 100644
--- a/tdd/Makefile
+++ b/tdd/Makefile
@@ -1,6 +1,6 @@
 # Variáveis
 CXX = g++
-CXXFLAGS = -I../sources
+CXXFLAGS = -I../sources -std=c++20
 LDFLAGS = -lm
 SRCS = main.cpp biblioteca-test.cpp \
        ../sources/ControladorObras.cpp \
diff --git a/tdd/biblioteca-test.cpp b/tdd/biblioteca-test.cpp
index b63419a..a1f3b0e 100644
--- a/tdd/biblioteca-test.cpp
+++ b/tdd/biblioteca-test.cpp
@@ -1,5 +1,6 @@
 #include <iostream>
 #include <tuple>
+#include <chrono>
 #include "doctest.h"
 #include "../sources/ControladorObras.hpp"
 #include "../sources/ControladorUsuarios.hpp"
@@ -9,15 +10,15 @@
 
 TEST_CASE("Biblioteca") {
   cout << "=> Instanciando Biblioteca" << endl;
-  Biblioteca bib;
+  Biblioteca& bib = Biblioteca::getInstance();
 
   cout << "==> Instanciando o Controlador de Obras" << endl;
-  ControladorObras contObras = bib.getContObras();
+  ControladorObras& contObras = bib.getContObras();
 
   cout << "==> Instanciando o Controlador de Usuarios" << endl;
-  ControladorUsuarios contUsuarios = bib.getContUsuarios();
+  ControladorUsuarios& contUsuarios = bib.getContUsuarios();
 
-  cout << "=================> Adicionar Usuario <================" << endl;
+  cout << "==================> Adicionar Usuario <=================" << endl;
   cout << "=> Criando Usuarios" << endl;
   contUsuarios.adicionarUsuario("Muriki", "12345", "Casa", "9999", "murikigy@gmail.com");
   contUsuarios.adicionarUsuario("Nico", "54321", "Apartamento", "8888", "nico@gmail.com");
@@ -31,7 +32,7 @@ TEST_CASE("Biblioteca") {
   CHECK(0 == contUsuarios.recuperarMultas("12345"));
   contUsuarios.mostrarDetalhes();
 
-  cout << "======================================================" << endl;
+  cout << "=======================================================" << endl;
 
   cout << "==================> Adicionar Obras <==================" << endl;
   cout << "=> Instanciando um Periodico: " << endl;
@@ -78,10 +79,38 @@ TEST_CASE("Biblioteca") {
   CHECK (1 == disponiveis);
   cout << "======================================================" << endl;
 
-  cout << "===============> Registrar Emprestimo <===============" << endl;
-  //usuario nao existe
-  //obra nao existe
-  //obra existe e pode emprestar
+  cout << "===================> Emprestimos <====================" << endl;
+  chrono::year_month_day hoje = {chrono::floor<chrono::days>(chrono::system_clock::now()) + chrono::days(3)};
+  chrono::year_month_day epoch = chrono::year_month_day{chrono::year{0}, chrono::month{0}, chrono::day{0}};
+
+  cout << "=> Usuario que nao existe tenta realizar um emprestimo: " << endl;
+  chrono::year_month_day dataDevolucao = contUsuarios.registrarEmprestimo("11234", l);
+  CHECK (int(epoch.year()) == int(dataDevolucao.year()));
+  CHECK (unsigned(epoch.month()) == unsigned(dataDevolucao.month()));
+  CHECK (unsigned(epoch.day()) == unsigned(dataDevolucao.day()));
+
+  cout << "=> Usuario que nao existe tenta retornar um emprestimo: " << endl;
+  CHECK (-1 == contUsuarios.retornarEmprestimo("11234", l));
+
+  cout << "=> Tenta emprestar uma obra que nao existe " << endl;
+  Periodico p1("Revista de Metodos", 2023, 5, 3);
+  dataDevolucao = contUsuarios.registrarEmprestimo("12345", p1);
+  CHECK (int(epoch.year()) == int(dataDevolucao.year()));
+  CHECK (unsigned(epoch.month()) == unsigned(dataDevolucao.month()));
+  CHECK (unsigned(epoch.day()) == unsigned(dataDevolucao.day()));
+
+  cout << "=> Tenta retornar uma obra que nao existe " << endl;
+  CHECK (-1 == contUsuarios.retornarEmprestimo("12345", p1));
+
+  cout << "=> Empresta uma obra que existe: " << endl;
+  dataDevolucao = contUsuarios.registrarEmprestimo("12345", p);
+  CHECK (int(hoje.year()) == int(dataDevolucao.year()));
+  CHECK (unsigned(hoje.month()) == unsigned(dataDevolucao.month()));
+  CHECK (unsigned(hoje.day()) == unsigned(dataDevolucao.day()));
+
+  cout << "=> Retorna uma obra que existe: " << endl;
+  CHECK (0 == contUsuarios.retornarEmprestimo("12345", p));
+
   //obra existe e ja tem tres
   cout << "======================================================" << endl;
 
@@ -103,4 +132,12 @@ TEST_CASE("Biblioteca") {
   //paga todo o valor
   //paga a mais
   cout << "======================================================" << endl;
+
+  cout << "=================> Pesquisar Obra <===================" << endl;
+  //livro titulo
+  //livro autor
+  //periodico titulo
+  //periodico titulo e ano
+  cout << "======================================================" << endl;
+
 }
-- 
GitLab