Skip to main content

Welcome to SASCOP BME SubTec

SASCOP BME SubTec is a comprehensive Django-based project management system designed for underwater subsea operations. This guide will help you set up and start using the system quickly.
What is SASCOP BME SubTec? A specialized platform for managing PTEs (Technical Project Proposals), OTEs (Work Orders), production tracking, and financial estimations in subsea engineering projects.

Quick Setup

1

Clone the Repository

Start by cloning the SASCOP BME SubTec repository to your local machine:
git clone <repository-url>
cd bme_subtec
2

Install Dependencies

Install all required Python packages using pip:
pip install -r requirements.txt
The system requires the following key packages:
Django==4.2.7
psycopg2-binary==2.9.7
gunicorn==21.2.0
django-anymail==14.0
whitenoise==6.4.0
python-dotenv==1.0.0
openpyxl==3.1.5
pandas==2.3.3
reportlab==4.0.4
qrcode==7.4.2
matplotlib==3.10.8
See the full requirements.txt at ~/workspace/source/requirements.txt
3

Configure Environment Variables

Create a .env file in the project root with your configuration:
# Security
SECRET_KEY=your-secret-key-here
DEBUG=True

# Database Configuration (PostgreSQL)
RDS_DB_NAME=postgres
RDS_USERNAME=postgres
RDS_PASSWORD=your-password
RDS_HOSTNAME=localhost
RDS_PORT=5432

# Email Configuration
EMAIL_HOST=smtp.gmail.com
EMAIL_PORT=587
EMAIL_USE_TLS=True
EMAIL_HOST_USER=[email protected]
EMAIL_HOST_PASSWORD=your-email-password
DEFAULT_FROM_EMAIL=SASCOP <[email protected]>

# Payment Gateway (Optional)
OPENPAY_MERCHANT_ID=
OPENPAY_PRIVATE_KEY=
OPENPAY_PRODUCTION=False
Never commit your .env file to version control. Add it to .gitignore.
4

Configure Database

The system uses PostgreSQL with SSL. Update your database settings:
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': os.environ.get('RDS_DB_NAME', 'postgres'),
        'USER': os.environ.get('RDS_USERNAME', 'postgres'),
        'PASSWORD': os.environ.get('RDS_PASSWORD', ''),
        'HOST': os.environ.get('RDS_HOSTNAME', 'localhost'),
        'PORT': os.environ.get('RDS_PORT', '5432'),
        'OPTIONS': {
            'sslmode': 'require',
        }
    }
}
For local development, you can comment out the production config and use the local configuration shown above.
5

Run Migrations

Apply database migrations to create all necessary tables:
python manage.py migrate
This will create tables for:
  • User authentication
  • PTEs (Technical Project Proposals)
  • OTEs (Work Orders)
  • Production tracking
  • Catalogs (Sites, Statuses, Types, etc.)
  • Estimations and billing
6

Create Superuser

Create an admin account to access the Django admin panel:
python manage.py createsuperuser
Follow the prompts to set username, email, and password.
7

Collect Static Files

Gather all static files for serving:
python manage.py collectstatic --noinput
8

Start the Development Server

Launch the Django development server:
python manage.py runserver
The application will be available at http://127.0.0.1:8000/

First Login

After starting the server, navigate to the login page:
http://127.0.0.1:8000/accounts/login/

Login with Username

Use the superuser credentials you created

Login with Email

The system also supports email-based authentication

Authentication Features

The custom login system (operaciones/views/login.py:11) supports:
  • Username or Email: Login with either your username or email address
  • Session Management: 2-hour session timeout (configurable)
  • Session Expiry Handling: Automatic redirect with clear messaging
  • Security: CSRF protection enabled
@ensure_csrf_cookie 
def custom_login(request):
    """Vista para login que acepta username o email"""
    if request.user.is_authenticated:
        return redirect('core:dashboard')
    
    if request.method == 'POST':
        username_or_email = request.POST.get('username')
        password = request.POST.get('password')
        
        # Try authenticating with username first
        user = authenticate(request, username=username_or_email, password=password)
        
        # If failed, try with email
        if user is None:
            try:
                user_by_email = User.objects.get(email__iexact=username_or_email)
                user = authenticate(request, username=user_by_email.username, password=password)
            except User.DoesNotExist:
                user = None
        
        if user is not None:
            login(request, user)
            request.session['last_activity'] = timezone.now().timestamp()
            return redirect('core:dashboard')

Verify Installation

Once logged in, you should see the main dashboard at:
http://127.0.0.1:8000/
1

Check Dashboard Access

The dashboard is the central hub defined in core/views/dashboard.py:6:
@login_required
def index(request):
    """Dashboard principal"""
    context = {
        'modulo_actual': 'dashboard'
    }
    return render(request, 'core/dashboard.html', context)
2

Access Main Modules

From the dashboard, you can access:
  • PTEs: Technical Project Proposals management
  • OTEs: Work Orders and operations
  • Production: Daily and monthly production tracking
  • Catalogs: Master data configuration
  • Centro de Consulta: Business intelligence and reporting
3

Verify Admin Panel

Access the Django admin at:
http://127.0.0.1:8000/admin/
Use your superuser credentials to manage data directly.

Production Deployment

Before deploying to production, ensure you:
  1. Set DEBUG=False in your .env file
  2. Configure proper ALLOWED_HOSTS
  3. Use a strong SECRET_KEY
  4. Enable SSL for database connections
  5. Configure WhiteNoise for static files

Using Gunicorn

For production, use Gunicorn as the WSGI server:
gunicorn bme_subtec.wsgi:application \
  --bind 0.0.0.0:8000 \
  --workers 4 \
  --timeout 120

Production Settings Checklist

bme_subtec/settings.py
# Security settings from settings.py:9-23
SECRET_KEY = os.getenv('SECRET_KEY', 'change-in-production')
DEBUG = os.getenv('DEBUG', 'True') == 'True'

ALLOWED_HOSTS = [
    'localhost',
    '127.0.0.1',
    'your-domain.com',
]

# CSRF Protection
CSRF_TRUSTED_ORIGINS = [
    'https://your-domain.com',
]

# Session Security
SESSION_COOKIE_SECURE = True  # HTTPS only
CSRF_COOKIE_SECURE = True     # HTTPS only
SESSION_COOKIE_AGE = 7200     # 2 hours
SESSION_SAVE_EVERY_REQUEST = True
bme_subtec/settings.py
# Static files with WhiteNoise
STATIC_URL = '/static/'
STATIC_ROOT = BASE_DIR / 'staticfiles'
STATICFILES_DIRS = [
    BASE_DIR / 'operaciones' / 'static',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware',  # After SecurityMiddleware
    # ... other middleware
]

Next Steps

Architecture

Learn about the system architecture and components

User Roles

Understand user roles and permissions

Workflow

Explore the PTE to OTE workflow

Installation

Detailed installation and configuration guide

Common Issues

If you encounter database connection errors:
  1. Verify PostgreSQL is running:
    sudo systemctl status postgresql
    
  2. Check your database credentials in .env
  3. For local development, disable SSL:
    # Comment out 'OPTIONS': {'sslmode': 'require'}
    
  4. Create the database if it doesn’t exist:
    psql -U postgres -c "CREATE DATABASE sascop_local;"
    
If static files (CSS, JS) aren’t loading:
  1. Run collectstatic again:
    python manage.py collectstatic --noinput
    
  2. Verify STATIC_ROOT path exists
  3. Check WhiteNoise is in MIDDLEWARE
  4. In development, Django serves static files automatically with DEBUG=True
If users are logged out too quickly:Adjust session timeout in settings.py:141:
SESSION_COOKIE_AGE = 7200  # 2 hours (in seconds)
SESSION_SAVE_EVERY_REQUEST = True
SESSION_EXPIRE_AT_BROWSER_CLOSE = False
The SessionTimeoutMiddleware at operaciones/middleware.py:5 manages automatic logout.
If emails aren’t sending:
  1. Verify SMTP settings in .env
  2. For Gmail, use an App Password (not your regular password)
  3. Test with Django shell:
    from django.core.mail import send_mail
    send_mail('Test', 'Message', '[email protected]', ['[email protected]'])
    
Alternative: Use SendGrid (commented in settings.py:157):
EMAIL_BACKEND = "anymail.backends.sendgrid.EmailBackend"
ANYMAIL = {
   "SENDGRID_API_KEY": os.getenv("SENDGRID_API_KEY", ""),
}

Getting Help

Documentation

Browse the complete documentation for detailed guides

Source Code

Review the source code at ~/workspace/source/
This quickstart covers the basics. For production deployments, review the Installation Guide for comprehensive configuration options.

Build docs developers (and LLMs) love