Skip to content

Commit

Permalink
Adding table with purchase courses
Browse files Browse the repository at this point in the history
  • Loading branch information
basshamut committed Sep 12, 2024
1 parent 6781630 commit ee118a5
Show file tree
Hide file tree
Showing 4 changed files with 178 additions and 152 deletions.
143 changes: 51 additions & 92 deletions backend/controller/PurchaseController.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,35 @@ const PurchaseService = require("../service/PurchaseService");
* /api/purchases/:
* get:
* summary: Get list of purchases
* description: Retrieve a list of all purchases with details such as email, birth date, purchase date, meet date, and price.
* tags:
* - Purchases
* description: Retrieve a list of all purchases with optional filters by date.
* tags: [Purchases]
* parameters:
* - in: query
* name: page
* schema:
* type: int32
* required: false
* description: Page number
* - in: query
* name: limit
* schema:
* type: int32
* required: false
* description: Limit
* - in: query
* name: startDate
* schema:
* type: string
* format: date
* required: false
* description: Filter purchases from this start date (inclusive).
* - in: query
* name: endDate
* schema:
* type: string
* format: date
* required: false
* description: Filter purchases up to this end date (inclusive).
* responses:
* '200':
* description: A list of purchases
Expand Down Expand Up @@ -114,101 +140,34 @@ router.post('/', async (req, res) => {
const savedPurchase = await PurchaseService.save(purchase);
res.json(savedPurchase);
} catch (error) {
res.status(500).json({error: error.message});
res.status(500).json({ error: error.message });
}
});

router.get('/', async (req, res) => {
try {
const purchases = [
{
email: 'test@test.com',
birthDate: '01/01/2000',
purchaseDate: '01/01/2021',
meetDate: '01/01/2021',
price: 15
},
{
email: 'jane@test.com',
birthDate: '05/05/1998',
purchaseDate: '02/02/2022',
meetDate: '01/01/2021',
price: 15
},
{
email: 'test@test.com',
birthDate: '01/01/2000',
purchaseDate: '01/01/2021',
meetDate: '01/01/2021',
price: 15
},
{
email: 'jane@test.com',
birthDate: '05/05/1998',
purchaseDate: '02/02/2022',
meetDate: '01/01/2021',
price: 15
},
{
email: 'test@test.com',
birthDate: '01/01/2000',
purchaseDate: '01/01/2021',
meetDate: '01/01/2021',
price: 15
},
{
email: 'jane@test.com',
birthDate: '05/05/1998',
purchaseDate: '02/02/2022',
meetDate: '01/01/2021',
price: 15
},
{
email: 'test@test.com',
birthDate: '01/01/2000',
purchaseDate: '01/01/2021',
meetDate: '01/01/2021',
price: 15
},
{
email: 'jane@test.com',
birthDate: '05/05/1998',
purchaseDate: '02/02/2022',
meetDate: '01/01/2021',
price: 15
},
{
email: 'test@test.com',
birthDate: '01/01/2000',
purchaseDate: '01/01/2021',
meetDate: '01/01/2021',
price: 15
},
{
email: 'jane@test.com',
birthDate: '05/05/1998',
purchaseDate: '02/02/2022',
meetDate: '01/01/2021',
price: 15
},
{
email: 'test@test.com',
birthDate: '01/01/2000',
purchaseDate: '01/01/2021',
meetDate: '01/01/2021',
price: 15
},
{
email: 'jane@test.com',
birthDate: '05/05/1998',
purchaseDate: '02/02/2022',
meetDate: '01/01/2021',
price: 15
}
]
res.json(purchases);
const page = parseInt(req.query.page) || 1;
const limit = parseInt(req.query.limit) || 10;
const startDate = req.query.startDate ? new Date(req.query.startDate) : null;
const endDate = req.query.endDate ? new Date(req.query.endDate) : null;

const { totalItems, totalPages, currentPage, itemsPerPage, purchases } = await PurchaseService.getPaginatedPurchases(page, limit, startDate, endDate);

const paginationInfo = {
currentPage,
itemsPerPage,
totalItems,
totalPages,
hasNextPage: currentPage < totalPages,
hasPreviousPage: currentPage > 1
};

res.json({
paginationInfo,
data: purchases
});
} catch (error) {
res.status(500).json({error: error.message});
res.status(500).json({ error: error.message });
}
});

Expand Down
84 changes: 56 additions & 28 deletions backend/service/PurchaseService.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,67 @@
const format = require('date-fns/format');
const purchaseRepository = require('../persistance/PurchaseRepository')
const meetRepository = require('../persistance/MeetRepository')
const purchaseRepository = require('../persistance/PurchaseRepository');
const meetRepository = require('../persistance/MeetRepository');
const userRepository = require("../persistance/UserRepository");
const mailerService = require('./MailerService')
const invoiceMakerService = require('./InvoiceMakerService')
const PurchaseService = {}
const {Op, Sequelize} = require('sequelize');
const PurchaseService = {};

PurchaseService.save = async function (purchase) {
const meet = await meetRepository.findByPk(purchase.meetId)
const user = await userRepository.findByPk(purchase.userId)
const newPurchase = await purchaseRepository.create({
const meet = await meetRepository.findByPk(purchase.meetId);
const user = await userRepository.findByPk(purchase.userId);
return await purchaseRepository.create({
userId: user.id,
meetId: meet.id,
price: meet.price,
purchaseDate: new Date()
})
purchaseDate: new Date(),
});
};

const dataForPdf = {
id: newPurchase.id,
purchaseDate: format(newPurchase.purchaseDate, 'dd/MM/yyyy HH:mm'),
price: meet.price,
items: [
{product: "Clase de Karate", quantity: 1, cost: meet.price}
]
PurchaseService.getPaginatedPurchases = async function (page = 1, limit = 10, startDate = null, endDate = null) {
const offset = (page - 1) * limit;

// Crear el objeto de filtrado por fecha si se proporcionan fechas válidas
const whereConditions = {};

if (startDate) {
const startOfDay = new Date(startDate);
startOfDay.setHours(0, 0, 0, 0); // 00:00:00.000

// Aplicar el filtro sobre la tabla Meet
whereConditions['$Meet.meetDate$'] = {[Op.gte]: startOfDay};
}

const invoicePdf = await invoiceMakerService.generateInvoicePdf(dataForPdf)
await mailerService.sendMail(
user.email,
'Purchase confirmation',
'Your purchase has been processed',
'Your purchase has been processed',
invoicePdf)
if (endDate) {
const endOfDay = new Date(endDate);
endOfDay.setHours(23, 59, 59, 999); // 23:59:59.999

// Aplicar el filtro sobre la tabla Meet
whereConditions['$Meet.meetDate$'] = {
...whereConditions['$Meet.meetDate$'],
[Op.lte]: endOfDay
};
}

// Consultar las compras con los filtros de fecha sobre Meet.meetDate, paginación y contar el total de registros
const {count, rows: purchases} = await purchaseRepository.findAndCountAll({
where: whereConditions, // Filtrar por las fechas en la tabla Meet
include: [
{model: userRepository, attributes: ['id', 'email']},
{model: meetRepository, attributes: ['id', 'meetDate']}
],
offset: offset,
limit: limit,
order: [['purchaseDate', 'DESC']], // Ordenar por fecha de compra descendente
});

// Calcular la información de paginación
const totalPages = Math.ceil(count / limit);

return newPurchase
}
return {
totalItems: count,
totalPages: totalPages,
currentPage: page,
itemsPerPage: limit,
purchases: purchases,
};
};

module.exports = PurchaseService
module.exports = PurchaseService;
59 changes: 43 additions & 16 deletions frontend/src/components/table/PurchasesTable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,48 @@ import {useState} from "react";
import {DataTable} from 'primereact/datatable';
import {Column} from 'primereact/column';
import {Calendar} from "primereact/calendar";
import 'primereact/resources/themes/saga-blue/theme.css'; // Elige el tema que prefieras
import 'primereact/resources/themes/saga-blue/theme.css';
import 'primereact/resources/primereact.min.css';
import 'primeicons/primeicons.css';
import {Button} from "primereact/button";
import useGetPurchases from "../../hooks/useGetPurchases";
import {hasSession, isUser} from "../../utils/session";
import {format} from 'date-fns';

export default function PurchasesTable() {
const userSession = hasSession();
const isUserValue = isUser();
const {purchases, error} = useGetPurchases(isUserValue, userSession);
const [selectedStartDate, setSelectedStartDate] = useState(new Date());
const [selectedEndDate, setSelectedEndDate] = useState(new Date());

function searchMeet() {
console.log('Meet saved');
}
const [page, setPage] = useState(1);
const [rowsPerPage, setRowsPerPage] = useState(4);

const [selectedStartDate, setSelectedStartDate] = useState(null); // Se inicia como null para no filtrar inicialmente
const [selectedEndDate, setSelectedEndDate] = useState(null);

const {purchases, totalRecords, error} = useGetPurchases(isUserValue, userSession, page, rowsPerPage, selectedStartDate, selectedEndDate);

const onPageChange = (event) => {
setPage(event.page + 1); // PrimeReact usa índices basados en 0
setRowsPerPage(event.rows); // Actualizar el número de filas por página
};

const formatDate = (dateString) => {
return format(new Date(dateString), 'dd/MM/yyyy');
};

const purchaseDateTemplate = (rowData) => {
return formatDate(rowData.purchaseDate);
};

const meetDateTemplate = (rowData) => {
return formatDate(rowData.Meet.meetDate);
};

return (
<div className="table-container">
<div className="flex">
<div style={{flex: 1, marginRight: '1rem'}}>
<label><b>Filtro por Fecha de Clase</b> </label>
</div>
<div style={{flex: 1, marginRight: '1rem'}}>
<Calendar value={selectedStartDate} onChange={(e) => setSelectedStartDate(e.value)}
dateFormat="dd/mm/yy" placeholder="Inicio"/>
Expand All @@ -31,15 +52,21 @@ export default function PurchasesTable() {
<Calendar value={selectedEndDate} onChange={(e) => setSelectedEndDate(e.value)}
dateFormat="dd/mm/yy" placeholder="Fin"/>
</div>
<div style={{flex: 1, marginRight: '1rem'}}>
<Button label="Buscar" onClick={searchMeet}/>
</div>
</div>
<div>
<DataTable value={purchases} paginator rows={4} globalFilterFields={['meetDate']}>
<Column field="email" header="Email del Usuario" sortable></Column>
<Column field="purchaseDate" header="Fecha de Compra" sortable></Column>
<Column field="meetDate" header="Fecha de Clase" sortable></Column>
<div style={{ marginTop: '20px' }}>
{error && <div>Error: {error}</div>} {/* Mostrar error si existe */}
<DataTable
value={purchases}
paginator
rows={rowsPerPage}
totalRecords={totalRecords}
onPage={onPageChange}
lazy
first={(page - 1) * rowsPerPage}
>
<Column field="User.email" header="Email del Usuario" sortable></Column>
<Column field="purchaseDate" header="Fecha de Compra" sortable body={purchaseDateTemplate}></Column>
<Column field="Meet.meetDate" header="Fecha de Clase" sortable body={meetDateTemplate}></Column>
<Column field="price" header="Precio" sortable></Column>
</DataTable>
</div>
Expand Down
Loading

0 comments on commit ee118a5

Please sign in to comment.