Skip to content

Repository files navigation

📦 Acopio

Multi-tenant humanitarian aid inventory management system
Sistema multi-tenant de gestión de inventario para ayuda humanitaria

PHP 8.3 Laravel 15 Filament 3 MySQL 8.4 Docker Redis


🇬🇧 English

Acopio is a web-based management platform designed to support humanitarian aid collection centers (e.g. Cruz Roja chapters, disaster relief organizations). It allows multiple independent organizations — each as a tenant — to manage their aid collection operations in complete isolation: donations received, transfers between centers, shipments to destinations, and real-time inventory with reporting.

✨ Key Features

Feature Description
🏢 Multi-Tenancy Complete data isolation between organizations. Each tenant has its own users, inventory, roles, and catalog.
🔐 Role-Based Access Control Powered by spatie/laravel-permission with Filament Shield. Roles and permissions are scoped per tenant.
📥 Aid Reception Log incoming donations per supply item across multiple collection centers.
🔄 Internal Transfers Track transfers of supplies between collection centers within the same organization.
📤 Shipments / Dispatches Register outgoing dispatches to final destinations.
📊 Statistics Dashboard Real-time KPI widgets, charts, and filterable data tables with date-range and center filters.
📄 Export to PDF & Excel Generate and download reception reports in PDF (DomPDF) and Excel (PhpSpreadsheet) formats.
🗂️ Base Catalog 10 categories, 42 subcategories, and 71 supply items pre-loaded as a reusable seed.
Quick Reception Form Streamlined Filament page for rapid donation entry without navigating CRUD tables.
🧭 Inventory Overview Cross-center inventory visibility with aggregated widgets and charts.

🏗️ Architecture & Tech Stack

Laravel 15 (PHP 8.3)
├── Filament v5              — Admin panel, CRUD resources, pages & widgets
├── spatie/laravel-permission — Role & Permission management (team-scoped per tenant)
├── filament-shield          — Auto-generated Filament policies from permissions
├── DomPDF                   — PDF report generation
├── PhpSpreadsheet           — Excel report generation
├── Laravel Sail + Docker    — Local development (PHP, MySQL 8.4, Redis)
└── Vite                     — Frontend asset compilation

Multi-tenancy is implemented via a lightweight custom solution:

  • A tenants table groups users and data under an organization.
  • A HasTenant trait automatically scopes all Eloquent queries to the current tenant using a Global Scope, preventing any data leakage between organizations.
  • A SetTenantPermissionsContext middleware configures Spatie's team ID on every request so permissions are evaluated in the correct tenant context.

📐 Data Model

Tenant
 └── Users (with roles scoped to tenant)
 └── CentroAcopio (Collection Center)
      ├── Recepcions  →  RecepcionDetalles  →  Insumo
      ├── Transferencias (origin / destination centers)
      └── Envios      →  EnvioDetalles      →  Destino

Catalog (isolated per tenant):
 Categoria → Subcategoria → Insumo

🛠️ Local Setup

Requirements: Docker Desktop, Git

# 1. Clone the repository
git clone https://github.com/Gusthere/acopio.git acopio && cd acopio

# 2. Copy environment file
cp .env.example .env

# 3. Install PHP dependencies (via temporary container)
docker run --rm -u "$(id -u):$(id -g)" \
    -v "$(pwd):/var/www/html" -w /var/www/html \
    laravelsail/php83-composer:latest \
    composer install --no-interaction

# 4. Start the development environment
./vendor/bin/sail up -d

# 5. Generate application key and run migrations
./vendor/bin/sail artisan key:generate
./vendor/bin/sail artisan migrate

# 6. Create your first tenant (with base catalog)
./vendor/bin/sail artisan tenants:create "My Organization" \
    --owner_email=admin@example.com \
    --owner_password=secret \
    --with-catalogo

# 7. Open the panel at http://localhost/admin

🧰 Artisan Commands

Command Description
tenants:create {name} Creates a new tenant with optional owner and base catalog
tenants:seed-catalogo {id} Seeds the base catalog into an existing tenant
db:seed Loads the global catalog (no tenant association)
# Full tenant setup in one command
php artisan tenants:create "Cruz Roja Bogotá" \
    --owner_email=admin@bogota.org \
    --owner_password=secret123 \
    --with-catalogo

# Seed catalog into an existing tenant (non-interactive)
php artisan tenants:seed-catalogo 3 --force

🐳 Production Deployment

The project ships a production Dockerfile based on serversideup/php:8.3-fpm-nginx. On container start, an entrypoint script automatically runs:

config:cache → route:cache → view:cache → storage:link → filament:optimize → migrate
docker build -t acopio:latest .
docker run -p 80:80 --env-file .env acopio:latest

📁 Project Structure

app/
├── Console/Commands/     # tenants:create, tenants:seed-catalogo
├── Filament/
│   ├── Pages/            # Dashboard, EstadisticasAcopio, InventarioCentros, RegistroRapidoRecepcion
│   ├── Resources/        # CRUD: CentroAcopio, Insumo, Recepcion, Envio, Transferencia, User…
│   └── Widgets/          # KPI stat cards, bar/donut charts, report data tables
├── Http/Middleware/      # SetTenantPermissionsContext
├── Models/
│   ├── Traits/HasTenant  # Global Scope for automatic tenant isolation
│   └── Scopes/           # Eloquent query scopes
└── Support/
    ├── ReportDataCollector.php    # Centralized report data aggregation logic
    └── UnidadMedidaFormatter.php  # Unit-of-measure display formatting

database/
├── migrations/           # 17 migration files
└── seeders/
    └── CatalogoComunSeeder.php    # Reusable base catalog seeder (10 cats / 42 subcats / 71 items)

🇪🇸 Español

Acopio es una plataforma de gestión web diseñada para apoyar centros de acopio de ayuda humanitaria (ej. seccionales de Cruz Roja, organizaciones de respuesta a desastres). Permite que múltiples organizaciones independientes — cada una como un tenant — gestionen sus operaciones de acopio en completo aislamiento: donaciones recibidas, transferencias entre centros, despachos a destinos e inventario en tiempo real con reportes exportables.

✨ Funcionalidades Principales

Funcionalidad Descripción
🏢 Multi-tenancy Aislamiento total de datos entre organizaciones. Cada tenant tiene sus propios usuarios, inventario, roles y catálogo.
🔐 Control de Acceso por Roles Usando spatie/laravel-permission con Filament Shield. Roles y permisos aislados por tenant.
📥 Recepción de Donaciones Registro de insumos recibidos por centro de acopio, con detalle por ítem.
🔄 Transferencias Internas Seguimiento de movimientos de insumos entre centros de la misma organización.
📤 Envíos / Despachos Registro de salidas hacia destinos finales.
📊 Dashboard de Estadísticas KPIs en tiempo real, gráficos y tablas filtrables por rango de fechas y centro.
📄 Exportar PDF y Excel Reportes de recepción descargables en PDF (DomPDF) y Excel con tabla nativa (PhpSpreadsheet).
🗂️ Catálogo Base 10 categorías, 42 subcategorías y 71 insumos pre-cargados como seed reutilizable.
Registro Rápido de Recepción Página Filament optimizada para el ingreso ágil de donaciones.
🧭 Vista de Inventario Visibilidad consolidada del inventario por centro con widgets y gráficos.

🏗️ Arquitectura y Stack Tecnológico

Laravel 15 (PHP 8.3)
├── Filament v5              — Panel administrativo, CRUD, páginas y widgets personalizados
├── spatie/laravel-permission — Roles y Permisos con soporte de equipos (teams) por tenant
├── filament-shield          — Políticas de Filament generadas automáticamente
├── DomPDF                   — Generación de reportes PDF
├── PhpSpreadsheet           — Generación de reportes Excel con tablas nativas
├── Laravel Sail + Docker    — Entorno de desarrollo (PHP 8.3, MySQL 8.4, Redis Alpine)
└── Vite                     — Compilación de assets frontend

La multi-tenancy está implementada con una solución liviana y personalizada:

  • La tabla tenants agrupa usuarios y datos bajo una organización.
  • El trait HasTenant aplica automáticamente un Global Scope de Eloquent en todos los modelos, garantizando el filtrado por tenant y evitando filtraciones de datos entre organizaciones.
  • El middleware SetTenantPermissionsContext configura el Team ID de Spatie en cada request, asegurando que los permisos se evalúen en el contexto del tenant correcto.

📐 Modelo de Datos

Tenant
 └── Usuarios (con roles aislados por tenant)
 └── CentroAcopio
      ├── Recepciones   →  RecepciónDetalles  →  Insumo
      ├── Transferencias (origen / destino entre centros)
      └── Envíos        →  EnvíoDetalles      →  Destino

Catálogo (aislado por tenant):
 Categoría → Subcategoría → Insumo

🛠️ Instalación Local

Requisitos: Docker Desktop, Git

# 1. Clonar el repositorio
git clone https://github.com/Gusthere/acopio.git acopio && cd acopio

# 2. Copiar el archivo de entorno
cp .env.example .env

# 3. Instalar dependencias PHP (contenedor temporal)
docker run --rm -u "$(id -u):$(id -g)" \
    -v "$(pwd):/var/www/html" -w /var/www/html \
    laravelsail/php83-composer:latest \
    composer install --no-interaction

# 4. Levantar el entorno de desarrollo
./vendor/bin/sail up -d

# 5. Generar clave de aplicación y ejecutar migraciones
./vendor/bin/sail artisan key:generate
./vendor/bin/sail artisan migrate

# 6. Crear el primer tenant con catálogo base
./vendor/bin/sail artisan tenants:create "Mi Organización" \
    --owner_email=admin@example.com \
    --owner_password=secret \
    --with-catalogo

# 7. Acceder al panel en http://localhost/admin

🧰 Comandos Artisan

Comando Descripción
tenants:create {name} Crea un nuevo tenant con owner y catálogo opcionales
tenants:seed-catalogo {id} Inyecta el catálogo base en un tenant existente
db:seed Carga el catálogo global (sin asociar a ningún tenant)
# Configuración completa de un tenant en un solo comando
php artisan tenants:create "Cruz Roja Bogotá" \
    --owner_email=admin@bogota.org \
    --owner_password=secret123 \
    --with-catalogo

# Inyectar catálogo en tenant existente (sin confirmación interactiva)
php artisan tenants:seed-catalogo 3 --force

🐳 Despliegue en Producción

El proyecto incluye un Dockerfile de producción basado en serversideup/php:8.3-fpm-nginx. Al iniciar el contenedor, un script de entrypoint ejecuta automáticamente:

config:cache → route:cache → view:cache → storage:link → filament:optimize → migrate
docker build -t acopio:latest .
docker run -p 80:80 --env-file .env acopio:latest

📁 Estructura del Proyecto

app/
├── Console/Commands/     # tenants:create, tenants:seed-catalogo
├── Filament/
│   ├── Pages/            # Dashboard, EstadisticasAcopio, InventarioCentros, RegistroRapidoRecepcion
│   ├── Resources/        # CRUD: CentroAcopio, Insumo, Recepcion, Envio, Transferencia, Usuario…
│   └── Widgets/          # Tarjetas KPI, gráficos de barras/dona, tablas de reporte
├── Http/Middleware/      # SetTenantPermissionsContext
├── Models/
│   ├── Traits/HasTenant  # Global Scope para aislamiento automático por tenant
│   └── Scopes/           # Query Scopes de Eloquent
└── Support/
    ├── ReportDataCollector.php    # Lógica centralizada de agregación de datos para reportes
    └── UnidadMedidaFormatter.php  # Formateo de unidades de medida

database/
├── migrations/           # 17 archivos de migración
└── seeders/
    └── CatalogoComunSeeder.php    # Seeder reutilizable del catálogo base (10 cat / 42 subcat / 71 insumos)

📦 Catálogo Base Incluido

# Categoría Subcategorías Insumos
1 Insumos médicos 4 11
2 Alimentos no perecederos 6 12
3 Ropa de niños 5 7
4 Ropa de adultos 5 7
5 Higiene personal 5 9
6 Limpieza y desinfección 3 5
7 Dormitorio y abrigo 4 5
8 Utensilios y cocina 3 6
9 Agua y saneamiento 3 3
10 Protección y emergencia 4 7
Total 42 71

📄 License / Licencia

This project is open-sourced software licensed under the MIT license.

Este proyecto es software de código abierto licenciado bajo la licencia MIT.

About

Multi-tenant administrative dashboard built with Laravel & Filament for centralized collection center management, inventory tracking, and intake records.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages