Author: Pedro Lucas Porcellis <porcellis@eletrotupi.com>
all: flesh out creating a bill
app/controllers/BillsController.php | 51 +++++++++++++++++++ app/daos/BillDAO.php | 82 +++++++++++++++++++++++++++++++ app/models/Bill.php | 69 ++++++++++++++++++++++++++ app/views/bill_create.php | 46 +++++++++++++++++
diff --git a/app/controllers/BillsController.php b/app/controllers/BillsController.php new file mode 100644 index 0000000000000000000000000000000000000000..ba3543b5e49a43011ad72a21d1a19bf9be6950a6 --- /dev/null +++ b/app/controllers/BillsController.php @@ -0,0 +1,51 @@ +<?php + +require_once __DIR__ . '/../daos/BillDAO.php'; +require_once __DIR__ . '/../daos/TagDAO.php'; +require_once __DIR__ . '/../models/Bill.php'; + +class BillsController { + private $billDAO; + private $tagDAO; + + public function __construct() { + $this->billDAO = new BillDAO(); + $this->tagDAO = new TagDAO(); + } + + public function create() { + $tags = $this->tagDAO->getAllTags(); + + return Template::render('bill_create', ['tags' => $tags]); + } + + public function store() { + $data = $_POST; + $bill = new Bill( + null, + $data['title'], + $data['amount'], + $data['due_date'], + isset($data['paid']) ? true : false, + $_SESSION['user_id'], + [] + ); + + $this->billDAO->create($bill, $data['tags']); + + header('Location: /dashboard'); + exit; + } + + public function edit($id) { + // TODO: Implement edit method + } + + public function update($id) { + // TODO: Implement update method + } + + public function destroy($id) { + // TODO: Implement destroy method + } +} diff --git a/app/daos/BillDAO.php b/app/daos/BillDAO.php new file mode 100644 index 0000000000000000000000000000000000000000..50eaa5a839935bcfdaa1b3ea11c236647097f48d --- /dev/null +++ b/app/daos/BillDAO.php @@ -0,0 +1,82 @@ +<?php + +require_once __DIR__ . '/../../config/database.php'; +require_once __DIR__ . '/../models/Bill.php'; + +class BillDAO { + private $db; + + public function __construct() { + $this->db = getDatabaseConnection(); + } + + public function findAllByUserId($userId) { + $sql = 'SELECT b.*, GROUP_CONCAT(t.name) AS tags + FROM bills b + LEFT JOIN bill_tags bt ON b.id = bt.bill_id + LEFT JOIN tags t ON bt.tag_id = t.id + WHERE b.user_id = :user_id + GROUP BY b.id'; + + $stmt = $this->db->prepare($sql); + $stmt->bindParam(':user_id', $userId); + $stmt->execute(); + + $bills = []; + + while ($billData = $stmt->fetch(PDO::FETCH_ASSOC)) { + $bills[] = new Bill( + $billData['id'], + $billData['title'], + $billData['amount'], + $billData['due_date'], + $billData['paid'], + $billData['user_id'], + $billData['tags'] + ); + } + + return $bills; + } + + public function create(Bill $bill, $tagIds) { + $this->db->beginTransaction(); + + try { + $stmt = $this->db->prepare(' + INSERT INTO bills (title, amount, due_date, paid, user_id) + VALUES (:title, :amount, :due_date, :paid, :user_id) + '); + + $stmt->bindValue(':title', $bill->getTitle()); + $stmt->bindValue(':amount', $bill->getAmount()); + $stmt->bindValue(':due_date', $bill->getDueDate()); + $stmt->bindValue(':paid', $bill->isPaid()); + $stmt->bindValue(':user_id', $bill->getUserId()); + $stmt->execute(); + + $billId = $this->db->lastInsertId(); + + foreach ($tagIds as $tagId) { + $stmt = $this->db->prepare(' + INSERT INTO bill_tags (bill_id, tag_id) + VALUES (:bill_id, :tag_id) + '); + + $stmt->bindParam(':bill_id', $billId); + $stmt->bindParam(':tag_id', $tagId); + $stmt->execute(); + } + + $this->db->commit(); + + $bill->setId($billId); + $bill->setTags($tagIds); + + return $bill; + } catch (Exception $e) { + $this->db->rollBack(); + throw $e; + } + } +} diff --git a/app/models/Bill.php b/app/models/Bill.php new file mode 100644 index 0000000000000000000000000000000000000000..18cec99b4cf17f00241059660735715bdd3ba052 --- /dev/null +++ b/app/models/Bill.php @@ -0,0 +1,69 @@ +<?php + +class Bill extends Base { + private $title; + private $amount; + private $dueDate; + private $paid; + + private $userId; + private $tags; + + public function __construct($id, $title, $amount, $dueDate, $paid, $userId, $tags) { + $this->id = $id; + $this->title = $title; + $this->amount = $amount; + $this->dueDate = $dueDate; + $this->paid = $paid; + $this->userId = $userId; + $this->tags = $tags; + } + + public function getTitle() { + return $this->title; + } + + public function getAmount() { + return $this->amount; + } + + public function getDueDate() { + return $this->dueDate; + } + + public function isPaid() { + return $this->paid; + } + + public function setAmount($amount) { + $this->amount = $amount; + } + + public function setDueDate($dueDate) { + $this->dueDate = $dueDate; + } + + public function setPaid($paid) { + $this->paid = $paid; + } + + public function getUserId() { + return $this->userId; + } + + public function getTags() { + return $this->tags; + } + + public function setTags($tags) { + $this->tags = $tags; + } + + public function toArray() { + return [ + 'amount' => $this->amount, + 'dueDate' => $this->dueDate, + 'paid' => $this->paid + ]; + } +} diff --git a/app/views/bill_create.php b/app/views/bill_create.php new file mode 100644 index 0000000000000000000000000000000000000000..eb2ae5d2b32e6a390ded886f9120ed75d3a10dca --- /dev/null +++ b/app/views/bill_create.php @@ -0,0 +1,46 @@ +<div class="container mx-auto mt-10"> + <h1 class="text-2xl font-bold text-gray-700 mb-6">Adicionar Novo Gasto</h1> + + <form action="/bills/create" method="POST" class="bg-white p-6 rounded shadow-md"> + <div class="mb-4"> + <label for="title" class="block text-sm font-medium text-gray-700">TÃtulo</label> + <input type="text" id="title" name="title" class="mt-1 block w-full border border-gray-300 rounded p-2" required /> + </div> + + <div class="mb-4"> + <label for="amount" class="block text-sm font-medium text-gray-700">Valor</label> + <input type="number" id="amount" name="amount" class="mt-1 block w-full border border-gray-300 rounded p-2" required /> + </div> + + <div class="mb-4"> + <label for="due_date" class="block text-sm font-medium text-gray-700">Vencimento</label> + <input type="date" id="due_date" name="due_date" class="mt-1 block w-full border border-gray-300 rounded p-2" required /> + </div> + + <div class="mb-4"> + <label class="block text-sm font-medium text-gray-700">Tags</label> + <?php foreach ($tags as $tag) : ?> + <div class="flex items-center mb-2"> + <input type="checkbox" name="tags[]" value="<?= htmlspecialchars($tag->getId()) ?>" id="tag_<?= $tag->getId() ?>" class="mr-2" /> + + <label for="tag_<?= $tag->getName() ?>" class="text-sm text-gray-700"> + <?= htmlspecialchars($tag->getName()) ?> + </label> + </div> + <?php endforeach; ?> + </div> + + <div class="mb-4"> + <label class="flex items-center text-sm font-medium text-gray-700"> + <input type="checkbox" name="paid" class="mr-2" /> + Pago? + </label> + </div> + + <div> + <button type="submit" class="bg-blue-600 text-white py-2 px-4 rounded hover:bg-blue-700"> + Salvar Gasto + </button> + </div> + </form> +</div>