https://github.com/workteam01/sistema_de_ventas_php
Sistema integral de Punto de Venta (POS) e Inventario en PHP 8.x con MySQL. MVC custom, PDO prepared statements, TCPDF, AdminLTE 3, control de roles, stack seguro. Documentación para colaboradores + skills IA. Código abierto MIT.
https://github.com/workteam01/sistema_de_ventas_php
adminlte bootstrap composer csrf-protection education inventory inventory-management mvc mysql open-source php point-of-sale pos psr-4 sales sistema-de-ventas tcpdf
Last synced: 28 days ago
JSON representation
Sistema integral de Punto de Venta (POS) e Inventario en PHP 8.x con MySQL. MVC custom, PDO prepared statements, TCPDF, AdminLTE 3, control de roles, stack seguro. Documentación para colaboradores + skills IA. Código abierto MIT.
- Host: GitHub
- URL: https://github.com/workteam01/sistema_de_ventas_php
- Owner: WorkTeam01
- License: mit
- Created: 2024-08-15T00:03:15.000Z (almost 2 years ago)
- Default Branch: master
- Last Pushed: 2026-05-22T22:53:54.000Z (29 days ago)
- Last Synced: 2026-05-23T00:27:11.815Z (29 days ago)
- Topics: adminlte, bootstrap, composer, csrf-protection, education, inventory, inventory-management, mvc, mysql, open-source, php, point-of-sale, pos, psr-4, sales, sistema-de-ventas, tcpdf
- Language: PHP
- Homepage:
- Size: 34 MB
- Stars: 2
- Watchers: 0
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
# Sistema de Ventas — PHP & MySQL
Sistema web de gestión de ventas con control de inventario, facturación en PDF, gestión de clientes/proveedores y
control de acceso por roles.








---
## Seguridad y Buenas Prácticas Implementadas
Este proyecto implementa una arquitectura MVC con PSR-4. Todos los módulos están completamente migrados. Mantiene los
estándares de seguridad web modernos:
- **Prevención de Inyecciones SQL**: 100% migrado a `PDO Prepared Statements` con _placeholders_ para parametrización.
- **Protección CSRF**: Intercepción de suplantaciones cruzadas mediante _tokens_ obligatorios en la sesión y formularios
mutables.
- **Escudos XSS**: Renderizado condicionado de entidades HTML (`htmlspecialchars()`) para neutralizar ejecución de
_scripts_ reflejados/almacenados.
- **Integridad Transaccional**: Operaciones de control de inventario/ventas están bajo control transaccional estricto (
`PDO::beginTransaction()` / `commit` / `rollBack`), garantizando un stock 100% consistente ante fallas.
- **Validaciones Back-End**: Todo envío por _POST_ recibe depuración estricta en el servidor para forzar cast a valores
numéricos, tipados seguros y sanitización antes del contacto con la BDD.
- **Encriptado Seguro**: Uso de API moderna de Hashes de contraseñas de PHP (`PASSWORD_DEFAULT` / BCRYPT).
- **Restablecimiento de Contraseña**: Flujo completo con tokens seguros (`bin2hex(random_bytes(32))`), expiración
de 1 hora, invalidación de un solo uso y envío por email vía PHPMailer + Gmail SMTP.
- **"Recordarme"**: Cookie httponly/samesite=Strict con token SHA-256 almacenado en BD; rotación en cada
auto-login; lifetime configurable (`REMEMBER_LIFETIME`, default 14 días).
- **Timeout de sesión**: Expiración por inactividad configurable (`SESSION_LIFETIME`, default 60 minutos).
- **Rate Limiting en Login**: Bloqueo temporal de cuenta tras 5 intentos fallidos consecutivos (15 minutos). Estado
persistido en columnas `login_intentos` y `login_bloqueado_hasta` de `tb_usuarios`, sin tabla adicional. Al quedar
bloqueado, el sistema indica al usuario usar la opción "¿Olvidaste tu contraseña?".
- **Optimizaciones de UI**: Control Sidebar de AdminLTE implementado de forma 100% nativa con un script dedicado,
integrando persistencia automatizada en `localStorage` y mecanismos Anti-FOUC para prevenir "flashes" blancos al
navegar con la temática oscura.
---
## Módulos
| Módulo | Descripción |
| --------------- | ----------------------------------------------------------------------------------------------------- |
| **Almacén** | Gestión de productos con stock, precios, imágenes y categorías |
| **Ventas** | POS wizard (Cliente → Carrito → Pago), creación inline de clientes, cálculo de totales y facturas PDF |
| **Compras** | Registro de compras a proveedores con actualización automática de stock |
| **Clientes** | Base de datos de clientes con historial de compras |
| **Proveedores** | Gestión de proveedores y datos de contacto |
| **Usuarios** | Administración de cuentas con roles y permisos |
| **Perfil** | Perfil propio para todos los roles: editar datos y cambiar contraseña |
| **Auditoría** | Registro de operaciones sensibles (eliminaciones, cambios de precio y rol) con vista de detalle |
---
## Requisitos
- PHP 8.x (extensiones: `pdo_mysql`, `gd`, `mbstring`, `json`)
- MySQL 5.7+ / MariaDB 10.4+
- Apache 2.4+ (incluido en XAMPP)
---
## Instalación
### 1. Clonar el repositorio
Colocar el proyecto dentro del directorio `htdocs` de XAMPP:
```bash
# Linux
git clone /opt/lampp/htdocs/Sistema_de_Ventas_PHP
# Windows
git clone C:\xampp\htdocs\Sistema_de_Ventas_PHP
# macOS
git clone /Applications/XAMPP/htdocs/Sistema_de_Ventas_PHP
```
### 2. Instalar dependencias (Composer)
```bash
composer install
```
### 3. Crear e importar la base de datos
**Linux / macOS:**
```bash
mysql -u root -p -e "CREATE DATABASE sistemadeventas;"
mysql -u root -p sistemadeventas < database/schema.sql
mysql -u root -p sistemadeventas < database/seeder.sql
```
**Windows** (desde `C:\xampp\mysql\bin\`):
```bat
mysql -u root -p -e "CREATE DATABASE sistemadeventas;"
mysql -u root -p sistemadeventas < C:\xampp\htdocs\Sistema_de_Ventas_PHP\database\schema.sql
mysql -u root -p sistemadeventas < C:\xampp\htdocs\Sistema_de_Ventas_PHP\database\seeder.sql
```
#### Credenciales por defecto
El seeder crea los siguientes usuarios de prueba:
| Rol | Email | Contraseña |
| ------------- | --------------------- | ------------ |
| Administrador | admin@sistema.com | admin123 |
| Vendedor | vendedor@sistema.com | vendedor123 |
| Comprador | comprador@sistema.com | comprador123 |
> **Importante:** Cambiar estas contraseñas antes de usar en producción.
### 4. Configurar la conexión
Copiar el archivo de entorno de ejemplo y editarlo con tus credenciales:
```bash
cp .env.example .env
```
Variables mínimas en `.env`:
```dotenv
DB_HOST=localhost
DB_NAME=sistemadeventas
DB_USER=root
DB_PASS=
APP_URL=http://localhost/Sistema_de_Ventas_PHP/public
APP_TIMEZONE=America/La_Paz
APP_DEBUG=false
SESSION_LIFETIME=60
REMEMBER_LIFETIME=14
```
Para habilitar el restablecimiento de contraseña por email, agregar también:
```dotenv
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=tu_email@gmail.com
MAIL_PASSWORD=xxxx_xxxx_xxxx_xxxx
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=tu_email@gmail.com
MAIL_FROM_NAME="Sistema de Ventas"
```
> `APP_URL` debe incluir `/public` — es la ruta al front controller.
> `MAIL_PASSWORD` debe ser una **Contraseña de Aplicación** de Google (no la contraseña de la cuenta).
### 5. Configurar permisos (Linux / macOS)
```bash
chmod 755 public/uploads/products/
```
### 6. Iniciar el servidor
**Linux:**
```bash
sudo /opt/lampp/lampp start
```
**Windows:** Abrir `xampp-control.exe` e iniciar Apache y MySQL.
**macOS:**
```bash
sudo /Applications/XAMPP/xamppfiles/xampp start
```
Acceder en: `http://localhost/Sistema_de_Ventas_PHP/public/`
---
## Control de Acceso por Roles
El sistema cuenta con tres roles. Cada módulo restringe el acceso según el rol del usuario autenticado:
| Rol | Acceso |
| --------------- | --------------------------------------------- |
| `Administrador` | Acceso completo a todos los módulos |
| `Vendedor` | Ventas, clientes y consulta de inventario |
| `Comprador` | Compras, proveedores y consulta de inventario |
---
## Stack Tecnológico
**Backend:** PHP con PDO (prepared statements), TCPDF (`tecnickcom/tcpdf`) para generación de facturas PDF, PHPMailer (
`phpmailer/phpmailer`) para envío de emails.
**Frontend:** AdminLTE 3.2.0 sobre Bootstrap 4, jQuery, DataTables, SweetAlert2.
**Base de datos:** MySQL con relaciones entre productos, ventas, compras, clientes y usuarios.
**Testing:** PHPUnit 11.x — suite Unit (lógica pura, sin BD) y suite Integration (SQLite in-memory). CI con GitHub Actions en PHP 8.2 y 8.3. Ver [Testing en CLAUDE.md](CLAUDE.md#testing).
---
## Estructura del Proyecto
```
Sistema_de_Ventas_PHP/
├── app/
│ ├── Controllers/ # Controladores MVC (Auth, Dashboard, User, Role, Category, Supplier, Client, Product, Purchase, Sale, ActivityLog)
│ ├── Core/ # Núcleo MVC (Router, Controller, Model, Database, Auth, Config)
│ ├── Helpers/ # Helpers PSR-4 (NumberToWords, InvoicePdf, PurchaseReportPdf, ActivityLogRenderer)
│ ├── Middleware/ # Middlewares PSR-4 (AuthMiddleware, GuestMiddleware, AdminMiddleware, SellerMiddleware)
│ ├── Models/ # Modelos de dominio (User, Role, Category, Supplier, Client, Product, Purchase, Sale, CartItem, ActivityLog)
│ └── Services/ # Servicios PSR-4 (EmailService — PHPMailer SMTP)
├── views/
│ ├── layouts/ # Plantillas compartidas (header, footer, messages) + partials/_sidebar.php
│ ├── errors/ # Páginas de error standalone (404, 403, 500)
│ ├── auth/ # Vistas de autenticación (login, forgot-password, reset-password, show-reset-link)
│ ├── dashboard/ # Vista del dashboard
│ ├── users/ # Vistas CRUD del módulo users
│ ├── roles/ # Módulo roles — patrón modal + AJAX (solo index.php)
│ ├── categories/ # Módulo categories — patrón modal + AJAX (solo index.php)
│ ├── suppliers/ # Vistas CRUD del módulo suppliers + partial/_modals.php
│ ├── clients/ # Vistas CRUD del módulo clients
│ ├── products/ # Vistas CRUD del módulo almacen (index, create, edit, show, delete)
│ ├── purchases/ # Vistas CRUD del módulo compras (index, create, edit, show)
│ ├── sales/ # Vistas del módulo ventas (index, create, show, delete, invoice vía TCPDF)
│ └── activity-log/ # Módulo auditoría (index, show) + partial/_data-panel.php, _item-accordion.php
├── routes/
│ └── web.php # Registro de rutas MVC
├── public/
│ ├── index.php # Front controller (bootstrap: Dotenv, BASE_URL, BASE_PATH, $pdo)
│ ├── css/
│ │ ├── core/ # Utilitarios globales (ui-components.css)
│ │ ├── modules/ # Estilos por módulo (auth/login.css, …)
│ │ ├── lib/ # Vendors CSS (adminlte/, fontawesome/, bootstrap/)
│ │ └── plugins/ # Plugins CSS (sweetalert2/, datatables/, select2/)
│ ├── js/
│ │ ├── core/ # Utilitarios globales (sweetalert-utils.js, control_sidebar.js)
│ │ ├── modules/ # Scripts por módulo (auth/login.js, users/users-index.js, …)
│ │ ├── lib/ # Vendors JS (jquery/, bootstrap/, adminlte/)
│ │ └── plugins/ # Plugins JS (sweetalert2/)
│ ├── uploads/products/ # Imágenes de productos (producto_default.png trackeado; resto ignorado)
│ └── templates/ # AdminLTE fuente completa (no modificar)
└── database/
├── schema.sql # Estructura de tablas
└── seeder.sql # Datos iniciales
```
---
## 📖 Documentación para Desarrolladores
| Archivo | Propósito |
| ---------------------------------- | ----------------------------------------------------------- |
| [AGENT.md](AGENT.md) | 🏗️ Arquitectura MVC, stack, convenciones, prohibiciones |
| [CLAUDE.md](CLAUDE.md) | 🛠️ Instrucciones operacionales locales (XAMPP, BD, rutas) |
| [PROMPTS.md](PROMPTS.md) | 📝 Plantillas de prompts efectivos para agentes IA |
| [CONTRIBUTING.md](CONTRIBUTING.md) | 🤝 Guía para colaboradores — flujo de PRs, commits, testing |
> **Requisito:** Lee [AGENT.md](AGENT.md) antes de contribuir. Es la fuente de verdad del proyecto.
---
## 🤝 Contribuciones
¿Te gustaría colaborar? ¡Excelente! Sigue estos pasos:
1. **Lee primero** [CONTRIBUTING.md](CONTRIBUTING.md) — contiene todo lo necesario
2. **Abre un issue** describiendo tu propuesta (feature, bug fix, docs)
3. **Fork + Branch:** `git checkout -b feature/nombre-funcionalidad`
4. **Código:** Sigue convenciones de [AGENT.md](AGENT.md)
5. **Commit:** Usa formato convencional → `feat(scope): description`
6. **Push + PR:** Abre pull request con descripción clara
**Código de conducta:** Sé respetuoso. Esperamos comentarios constructivos en las PRs.
---
## 📄 Licencia
Proyecto de código abierto distribuido bajo la **[Licencia MIT](LICENSE)**.
Eres libre de usar, modificar y distribuir este proyecto con fines educativos y comerciales.