This document describes the comprehensive document number management system for the APM application, including assignment, monitoring, and conflict resolution.
The document numbering system automatically assigns unique document numbers to various types of records in the system. It uses a queue-based approach to ensure proper handling of document returns, resets, and conflicts.
| Type | Code | Description | Example |
|------|------|-------------|---------|
| Quarterly Matrix | QM | Regular activities in matrices | AU/CDC/EPR/IM/QM/012 |
| Single Memo | SM | Single memo activities | AU/CDC/EPR/IM/SM/005 |
| Non-Travel Memo | NT | Non-travel memos | AU/CDC/EPR/IM/NT/003 |
| Special Memo | SPM | Special memos | AU/CDC/EPR/IM/SPM/001 |
| Change Request | CR | Change requests for activities, memos, and ARFs | AU/CDC/EPR/IM/CR/007 |
| Service Request | SR | Service requests | AU/CDC/EPR/IM/SR/002 |
| Request ARF | ARF | Request ARFs | AU/CDC/EPR/IM/ARF/004 |
Change Requests (CR) are automatically assigned document numbers when created. The document number format follows the standard pattern:
AU/CDC/{DIVISION_SHORT_NAME}/IM/CR/{COUNTER}
Features:
Usage:
# Assign missing document numbers for change requests
php artisan assign:missing-document-numbers --table=change_requests --user=558
# Monitor change requests without document numbers
php artisan monitor:document-numbers --auto-assign --user=558
Assigns document numbers to records that are missing them.
# Basic usage - assign missing document numbers
php artisan assign:missing-document-numbers
# Use queue system (recommended for production)
php artisan assign:missing-document-numbers --queue --user=558
# Dry run to see what would be assigned
php artisan assign:missing-document-numbers --dry-run --user=558
# Assign for specific table only
php artisan assign:missing-document-numbers --table=activities --user=558
php artisan assign:missing-document-numbers --table=change_requests --user=558
# Force assignment even if document numbers exist
php artisan assign:missing-document-numbers --force --user=558
Options:
--dry-run: Show what would be assigned without making changes--table=: Assign numbers for specific table only--force: Force assignment even if document numbers exist--user=558: User ID to use for session and audit logging (default: 558)--queue: Dispatch jobs to queue instead of immediate assignmentContinuously monitors for records without document numbers and optionally assigns them.
# One-time check
php artisan monitor:document-numbers --user=558
# Auto-assign missing document numbers
php artisan monitor:document-numbers --auto-assign --user=558
# Run as daemon (continuous monitoring)
php artisan monitor:document-numbers --daemon --user=558
# Custom check interval (default: 300 seconds = 5 minutes)
php artisan monitor:document-numbers --daemon --check-interval=60 --user=558
Options:
--user=558: User ID to use for session and audit logging (default: 558)--auto-assign: Automatically assign document numbers to records that need them--check-interval=300: Check interval in seconds (default: 5 minutes)--daemon: Run as daemon to continuously monitorResolves conflicts in document number assignment.
# Fix all conflicts
php artisan fix:document-number-conflicts
# Dry run to see what would be fixed
php artisan fix:document-number-conflicts --dry-run
# Fix for specific division
php artisan fix:document-number-conflicts --division=1
# Reset counters after fixing
php artisan fix:document-number-conflicts --reset-counters
The document number assignment uses Laravel's queue system to ensure proper processing and conflict resolution. Background jobs do not require sessions - they run independently of HTTP requests.
Make sure the queue worker is running:
# Process jobs once
php artisan queue:work --once
# Run queue worker continuously
php artisan queue:work
# Run with specific queue
php artisan queue:work --queue=default
The system uses the default queue for document number assignment jobs. Ensure your queue configuration is properly set up in config/queue.php.
Important: Background jobs run without HTTP context, so they don't have access to sessions, cookies, or request data. The --user parameter in commands is only for reference and logging purposes.
Document numbers are automatically assigned when:
HasDocumentNumber trait automatically dispatches AssignDocumentNumberJobThe system includes robust conflict resolution:
Set up a cron job to run the monitor command regularly:
# Add to crontab - check every 5 minutes
*/5 * * * * cd /path/to/apm && php artisan monitor:document-numbers --auto-assign --user=558
# Or check every hour
0 * * * * cd /path/to/apm && php artisan monitor:document-numbers --auto-assign --user=558
Create a systemd service for continuous monitoring:
# Create service file
sudo nano /etc/systemd/system/apm-document-monitor.service
# Add content:
[Unit]
Description=APM Document Number Monitor
After=network.target
[Service]
Type=simple
User=www-data
WorkingDirectory=/opt/homebrew/var/www/staff/apm
ExecStart=/usr/bin/php artisan monitor:document-numbers --daemon --auto-assign --user=558
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
# Enable and start service
sudo systemctl enable apm-document-monitor.service
sudo systemctl start apm-document-monitor.service
- Check if queue worker is running
- Verify user ID has proper permissions
- Check logs for errors
- Run php artisan fix:document-number-conflicts
- Check for duplicate numbers across tables
- Ensure queue worker is running
- Check queue configuration
- Verify database connection
Check the following logs for issues:
# Laravel logs
tail -f storage/logs/laravel.log
# Queue logs
tail -f storage/logs/queue.log
# Systemd service logs
sudo journalctl -u apm-document-monitor.service -f
// Generate document number for a model
$documentNumber = DocumentNumberService::generateForModel($model, 'QM');
// Generate document number directly
$documentNumber = DocumentNumberService::generateDocumentNumber('QM', 'IM', 1);
// Check if document number is unique
$isUnique = DocumentNumberService::isDocumentNumberUnique('AU/CDC/EPR/IM/QM/012');
// Find next available number
$nextNumber = DocumentNumberService::findNextAvailableNumber('QM', 'IM', 1);
// Reset counter after deletion
DocumentNumberService::resetCounterAfterDeletion('QM', 'IM', 1);
// Dispatch job for document number assignment
AssignDocumentNumberJob::dispatch($model, 'QM');
// Dispatch with delay
AssignDocumentNumberJob::dispatch($model, 'QM')->delay(now()->addMinutes(5));