# 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)
