- Created migration scripts for AnyDesk sessions and hardware assets. - Implemented apply_migration_115.py to execute migration for AnyDesk sessions. - Added set_customer_wiki_slugs.py script to update customer wiki slugs based on a predefined folder list. - Developed run_migration.py to apply AnyDesk migration schema. - Added tests for Service Contract Wizard to ensure functionality and dry-run mode.
202 lines
7.4 KiB
Markdown
202 lines
7.4 KiB
Markdown
# Service Contract Migration Wizard - Implementation Summary
|
|
|
|
## ✅ What Was Built
|
|
|
|
A step-by-step wizard that migrates Vtiger service contracts to Hub systems:
|
|
- **Cases** → Archived to `tticket_archived_tickets`
|
|
- **Timelogs** → Transferred as klippekort top-ups (prepaid card hours)
|
|
|
|
Features:
|
|
- ✅ Dry-run toggle (preview mode without database writes)
|
|
- ✅ Step-by-step review of each case/timelog
|
|
- ✅ Manual klippekort selection per timelog
|
|
- ✅ Progress tracking and summary report
|
|
- ✅ Read-only from Vtiger (no writes back to Vtiger)
|
|
|
|
## 🎯 Files Created/Modified
|
|
|
|
### New Files:
|
|
1. **[app/timetracking/backend/service_contract_wizard.py](app/timetracking/backend/service_contract_wizard.py)** (275 lines)
|
|
- Core wizard service with all business logic
|
|
- Methods: `load_contract_detailed_data()`, `archive_case()`, `transfer_timelog_to_klippekort()`, `get_wizard_summary()`
|
|
- Dry-run support built into each method
|
|
|
|
2. **[app/timetracking/frontend/service_contract_wizard.html](app/timetracking/frontend/service_contract_wizard.html)** (650 lines)
|
|
- Complete wizard UI with Nordic design
|
|
- Contract dropdown selector
|
|
- Progress bar with live counters
|
|
- Current item display with conditional klippekort dropdown
|
|
- Summary report on completion
|
|
|
|
### Modified Files:
|
|
1. **[app/services/vtiger_service.py](app/services/vtiger_service.py)** (+65 lines)
|
|
- Added `get_service_contracts(account_id=None)` - Fetch active service contracts
|
|
- Added `get_service_contract_cases(contract_id)` - Fetch cases linked to contract
|
|
- Added `get_service_contract_timelogs(contract_id)` - Fetch timelogs linked to contract
|
|
|
|
2. **[app/timetracking/backend/models.py](app/timetracking/backend/models.py)** (+70 lines)
|
|
- `ServiceContractBase` - Base contract model
|
|
- `ServiceContractItem` - Single case/timelog item
|
|
- `ServiceContractWizardData` - Complete contract data for wizard
|
|
- `ServiceContractWizardAction` - Action result (archive/transfer)
|
|
- `ServiceContractWizardSummary` - Final summary
|
|
- `TimologTransferRequest` - Request model for timelog transfer
|
|
- `TimologTransferResult` - Transfer result
|
|
|
|
3. **[app/timetracking/backend/router.py](app/timetracking/backend/router.py)** (+180 lines)
|
|
- `GET /api/v1/timetracking/service-contracts` - List contracts dropdown
|
|
- `POST /api/v1/timetracking/service-contracts/wizard/load` - Load contract data
|
|
- `POST /api/v1/timetracking/service-contracts/wizard/archive-case` - Archive case
|
|
- `POST /api/v1/timetracking/service-contracts/wizard/transfer-timelog` - Transfer timelog
|
|
- `GET /api/v1/timetracking/service-contracts/wizard/customer-cards/{customer_id}` - Get klippekort
|
|
|
|
4. **[app/timetracking/frontend/views.py](app/timetracking/frontend/views.py)** (+5 lines)
|
|
- Added frontend route: `/timetracking/service-contract-wizard`
|
|
|
|
## 🚀 How to Test
|
|
|
|
### 1. Start the API
|
|
```bash
|
|
docker-compose up -d api
|
|
docker-compose logs -f api
|
|
```
|
|
|
|
### 2. Access the Wizard
|
|
```
|
|
http://localhost:8000/timetracking/service-contract-wizard
|
|
```
|
|
|
|
### 3. Dry-Run Mode (Recommended First)
|
|
1. Check the "Preview Mode" checkbox at top (enabled by default)
|
|
2. Select a service contract from dropdown
|
|
3. Review each case/timelog and click "Gem & Næste"
|
|
4. No data is written to database in dry-run mode
|
|
5. Review summary report to see what WOULD be changed
|
|
|
|
### 4. Live Mode
|
|
1. **Uncheck** "Preview Mode" checkbox
|
|
2. Select same or different contract
|
|
3. Process items - changes ARE committed to database
|
|
4. Cases are exported to `tticket_archived_tickets`
|
|
5. Timelogs are added to klippekort via top-up transaction
|
|
|
|
## 🔍 Database Changes
|
|
|
|
### Dryrun Mode:
|
|
- All operations are **logged** but **NOT committed**
|
|
- Queries are constructed but rolled back
|
|
- UI shows what WOULD happen
|
|
|
|
### Live Mode:
|
|
- Cases are inserted into `tticket_archived_tickets` with:
|
|
- `source_system = 'vtiger_service_contract'`
|
|
- `external_id = vtiger case ID`
|
|
- Full case data in `raw_data` JSONB field
|
|
|
|
- Timelogs create transactions in `tticket_prepaid_transactions` with:
|
|
- `transaction_type = 'top_up'`
|
|
- Hours added to klippekort `purchased_hours`
|
|
- Description references vTiger timelog
|
|
|
|
## 📊 Data Flow
|
|
|
|
```
|
|
Vtiger Service Contract
|
|
↓
|
|
SelectContract (dropdown)
|
|
↓
|
|
LoadContractData
|
|
├─ Cases → Archive to tticket_archived_tickets
|
|
└─ Timelogs → Transfer to klippekort (top-up)
|
|
↓
|
|
WizardProgress (step-by-step review)
|
|
├─ [DRY RUN] Preview mode (no DB writes)
|
|
└─ [LIVE] Commit to database
|
|
↓
|
|
Summary Report
|
|
├─ Cases archived: N
|
|
├─ Hours transferred: N
|
|
└─ Failed items: N
|
|
```
|
|
|
|
## 🔐 Safety Features
|
|
|
|
1. **Dry-run mode enabled by default** - Users see what WOULD happen first
|
|
2. **Customer linking** - Looks up Hub customer ID from vTiger account
|
|
3. **Klippekort validation** - Verifies card belongs to customer before transfer
|
|
4. **Read-only from Vtiger** - No writes back to Vtiger (only reads)
|
|
5. **Transaction handling** - Each operation is atomic
|
|
6. **Audit logging** - All actions logged with DRY RUN/COMMITTED markers
|
|
|
|
## 🛠️ Technical Details
|
|
|
|
### Wizard Service (`ServiceContractWizardService`)
|
|
- Stateless service class
|
|
- All methods are static
|
|
- Database operations via `execute_query()` helpers
|
|
- Klippekort transfers via `KlippekortService.top_up_card()`
|
|
|
|
### Frontend UI
|
|
- Vanilla JavaScript (no frameworks)
|
|
- Nordic Top design system (matches existing Hub UI)
|
|
- Responsive Bootstrap 5 grid
|
|
- Real-time progress updates
|
|
- Conditional klippekort dropdown (only for timelogs)
|
|
|
|
### API Endpoints
|
|
- RESTful architecture
|
|
- All endpoints support `dry_run` query parameter
|
|
- Request/response models use Pydantic validation
|
|
- Comprehensive error handling with HTTPException
|
|
|
|
## 📝 Logging Output
|
|
|
|
### Dry-Run Mode:
|
|
```
|
|
🔍 DRY RUN: Would archive case 1x123: 'Case Title'
|
|
🔍 DRY RUN: Would transfer 5h to card 42 from timelog 2x456
|
|
```
|
|
|
|
### Live Mode:
|
|
```
|
|
✅ Archived case 1x123 to tticket_archived_tickets (ID: 1234)
|
|
✅ Transferred 5h from timelog 2x456 to card 42
|
|
```
|
|
|
|
## 🐛 Troubleshooting
|
|
|
|
### Contracts dropdown is empty:
|
|
- Verify Vtiger integration is configured (VTIGER_URL, VTIGER_USERNAME, VTIGER_API_KEY in .env)
|
|
- Check vTiger has active ServiceContracts
|
|
- Check API user has access to ServiceContracts module
|
|
|
|
### Klippekort dropdown empty for customer:
|
|
- Customer may not have any active prepaid cards
|
|
- Or customer is not linked between Vtiger account and Hub customer
|
|
- Create a prepaid card for the customer first
|
|
|
|
### Dry-run mode not working:
|
|
- Ensure checkbox is checked
|
|
- Check browser console for JavaScript errors
|
|
- Verify `dry_run` parameter is passed to API endpoints
|
|
|
|
## 📋 Next Steps
|
|
|
|
1. **Test with sample data** - Create test service contract in Vtiger
|
|
2. **Verify database changes** - Query `tticket_archived_tickets` post-migration
|
|
3. **Monitor klippekort** - Check `tticket_prepaid_transactions` for top-up entries
|
|
4. **Adjust as needed** - Tweak timelog filtering or case mapping based on results
|
|
|
|
## 🔗 Related Components
|
|
|
|
- **Klippekort System**: [app/ticket/backend/klippekort_service.py](app/ticket/backend/klippekort_service.py)
|
|
- **Archive System**: Database table `tticket_archived_tickets`
|
|
- **Timetracking Module**: [app/timetracking/](app/timetracking/)
|
|
- **Vtiger Integration**: [app/services/vtiger_service.py](app/services/vtiger_service.py)
|
|
|
|
---
|
|
|
|
**Status**: ✅ Ready for testing and deployment
|
|
**Estimated Time to Test**: 15-20 minutes
|
|
**Database Dependency**: PostgreSQL (no migrations needed - uses existing tables)
|