stupa-pdf-api/docs/COMPARISON_OFFERS_FEATURE.md

167 lines
6.4 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Comparison Offers Feature Documentation
## Overview
The comparison offers feature requires users to provide at least 3 comparison offers for each cost position in their application. This ensures transparency and cost-effectiveness in funding requests. Users can alternatively provide a justification if comparison offers are not applicable for specific cost positions.
## Features
- **3 Offers Requirement**: Each cost position must have at least 3 comparison offers
- **Justification Alternative**: Users can mark that no offers are required and provide a detailed justification
- **Attachment Support**: Each offer can be linked to an uploaded attachment (e.g., quotes, invoices)
- **Visual Indicators**: Cost positions without sufficient offers are highlighted with warning icons
- **Status Tracking**: Real-time status display showing offer count and completion status
## Database Schema
### `comparison_offers` Table
Stores comparison offers for cost positions:
- `id` (INT, PRIMARY KEY) - Unique identifier
- `application_id` (INT) - References the application
- `cost_position_index` (INT) - Index of the cost position in the costs array
- `supplier_name` (VARCHAR 255) - Name of the supplier/vendor
- `amount` (INT) - Offer amount in cents
- `description` (TEXT) - Optional description of the offer
- `url` (VARCHAR 500) - Optional URL to offer document or webpage
- `attachment_id` (INT) - Optional reference to an attachment
- `created_at` (DATETIME) - Creation timestamp
- `updated_at` (DATETIME) - Last update timestamp
### `cost_position_justifications` Table
Stores justifications for positions without offers:
- `id` (INT, PRIMARY KEY) - Unique identifier
- `application_id` (INT) - References the application
- `cost_position_index` (INT) - Index of the cost position
- `no_offers_required` (INT) - Boolean flag (0/1)
- `justification` (TEXT) - Required explanation when no_offers_required is 1
- `created_at` (DATETIME) - Creation timestamp
- `updated_at` (DATETIME) - Last update timestamp
## API Endpoints
### Create Comparison Offer
`POST /api/applications/{pa_id}/costs/{cost_position_index}/offers`
- Request body:
```json
{
"supplier_name": "Supplier GmbH",
"amount": 1500.50,
"description": "Optional description",
"url": "https://beispiel.de/angebot.pdf",
"attachment_id": 123
}
```
- Returns: ComparisonOfferResponse with offer details
### Get Cost Position Offers
`GET /api/applications/{pa_id}/costs/{cost_position_index}/offers`
- Returns: CostPositionOffersResponse with all offers and justification info
### Delete Comparison Offer
`DELETE /api/applications/{pa_id}/costs/{cost_position_index}/offers/{offer_id}`
- Removes a specific offer
### Update Cost Position Justification
`PUT /api/applications/{pa_id}/costs/{cost_position_index}/justification`
- Request body:
```json
{
"no_offers_required": true,
"justification": "Detailed explanation why no offers are needed..."
}
```
## Frontend Components
### ComparisonOffersDialog
Main dialog for managing offers for a cost position:
- Add/remove comparison offers
- Add URL links to online offers
- Link attachments to offers (either URL or attachment required)
- Mark position as not requiring offers
- Provide justification when needed
### CostPositionsList
Enhanced cost positions list with offer status:
- Visual indicators for offer status
- Warning icons for incomplete positions
- Quick access to manage offers
- Real-time status updates
## User Interface
### Status Indicators
-**Green checkmark**: Position has 3+ offers
- **Blue info icon**: Position marked as not requiring offers (with justification)
- ⚠️ **Yellow warning**: Position needs more offers or justification
- 🔄 **Loading spinner**: Status being loaded
### Validation Rules
1. Each cost position must have either:
- At least 3 comparison offers, OR
- Be marked as "no offers required" with a justification (min. 10 characters)
2. Cost positions without sufficient offers are highlighted in the list
3. Offers must include:
- Supplier name (required, must be unique per cost position)
- Amount (required, must be greater than 0)
- Either URL or attachment (at least one required)
- Description (optional)
4. Duplicate suppliers: Each supplier can only have one offer per cost position
5. URL format: Must be a valid HTTP/HTTPS URL (protocol is auto-added if missing)
6. Amount format: Accepts both comma and period as decimal separator
## Migration
To add the comparison offers tables to your database:
```sql
mysql -u your_user -p your_database < src/migrations/add_comparison_offers_tables.sql
mysql -u your_user -p your_database < src/migrations/add_url_to_comparison_offers.sql
```
## Usage Example
### In Cost Positions List
```tsx
<CostPositionsList
costs={formData.costs}
paId={applicationId}
paKey={applicationKey}
isAdmin={false}
readOnly={false}
attachments={availableAttachments}
/>
```
### Managing Offers
1. Click "Angebote" button next to any cost position
2. In the dialog:
- Add up to 5 comparison offers
- Link existing attachments to offers
- OR check "no offers required" and provide justification
3. Save changes
## Best Practices
1. **Encourage Early Collection**: Remind users to collect offers before starting the application
2. **Clear Instructions**: Provide examples of valid justifications for positions without offers
3. **Attachment Organization**: Name attachment files clearly to easily link them to offers
4. **Regular Validation**: Check offer status before submission
## Error Handling
- **Duplicate Suppliers**: Shows user-friendly error message when trying to add the same supplier twice
- **Invalid URLs**: Automatically prepends https:// if missing, validates format
- **Invalid Amounts**: Real-time validation with support for German number format (comma as decimal)
- **Missing Data**: Clear error messages when required fields are missing
## Future Enhancements
1. **Bulk Import**: Import multiple offers from CSV/Excel
2. **Templates**: Save common suppliers for quick reuse
3. **Price Comparison**: Automatic highlighting of best offer
4. **History Tracking**: Track changes to offers over time
5. **Export Function**: Export all offers as PDF/Excel report
6. **Smart Validation**: Detect duplicate suppliers or suspicious patterns
7. **URL Validation**: Automatic checking of URL availability and validity
8. **Screenshot Capture**: Automatic capture of web-based offers for archival